PageRenderTime 59ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 1ms

/htdocs/wp-content/plugins/sitepress-multilingual-cms/sitepress.class.php

https://bitbucket.org/dkrzos/phc
PHP | 7536 lines | 6118 code | 977 blank | 441 comment | 1579 complexity | 2e8344fa7eabc35e73b9aac072ac0559 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. class SitePress{
  3. private $settings;
  4. private $active_languages = array();
  5. private $this_lang;
  6. private $wp_query;
  7. private $admin_language = null;
  8. private $user_preferences = array();
  9. public $queries = array();
  10. function __construct(){
  11. global $wpdb, $pagenow;
  12. $this->settings = get_option('icl_sitepress_settings');
  13. if(is_null($pagenow) && is_multisite()){
  14. include ICL_PLUGIN_PATH . '/inc/hacks/vars-php-multisite.php';
  15. }
  16. if(false != $this->settings){
  17. $this->verify_settings();
  18. }
  19. if(isset($_GET['icl_action'])){
  20. require_once ABSPATH . WPINC . '/pluggable.php';
  21. if($_GET['icl_action']=='reminder_popup'){
  22. add_action('init', array($this, 'reminders_popup'));
  23. }
  24. elseif($_GET['icl_action']=='dismiss_help'){
  25. $this->settings['dont_show_help_admin_notice'] = true;
  26. $this->save_settings();
  27. }elseif($_GET['icl_action']=='dbdump' ){
  28. include_once ICL_PLUGIN_PATH . '/inc/functions-troubleshooting.php';
  29. add_action('init', 'icl_troubleshooting_dumpdb');
  30. }
  31. }
  32. if(isset($_GET['page']) && $_GET['page']== ICL_PLUGIN_FOLDER . '/menu/troubleshooting.php' && isset($_GET['debug_action'])){
  33. ob_start();
  34. }
  35. if(isset($_REQUEST['icl_ajx_action'])){
  36. add_action('init', array($this, 'ajax_setup'));
  37. }
  38. add_action('admin_footer', array($this, 'icl_nonces'));
  39. // Process post requests
  40. if(!empty($_POST)){
  41. add_action('init', array($this,'process_forms'));
  42. }
  43. add_action('plugins_loaded', array($this,'init'), 1);
  44. add_action('plugins_loaded', array($this,'initialize_cache'), 0);
  45. add_action('admin_print_scripts', array($this,'js_scripts_setup'));
  46. add_action('admin_print_styles', array($this,'css_setup'));
  47. // Administration menus
  48. add_action('admin_menu', array($this, 'administration_menu'));
  49. add_action('init', array($this,'plugin_localization'));
  50. if($this->settings['existing_content_language_verified']){
  51. // Post/page language box
  52. if($pagenow == 'post.php' || $pagenow == 'post-new.php'){
  53. add_action('admin_head', array($this,'post_edit_language_options'));
  54. }
  55. // Post/page save actions
  56. add_action('save_post', array($this,'save_post_actions'), 10, 2);
  57. //add_action('update_post_metadata', array($this,'pre_update_post_meta'), 10, 5);
  58. add_action('updated_post_meta', array($this,'update_post_meta'), 100, 4);
  59. add_action('added_post_meta', array($this,'update_post_meta'), 100, 4);
  60. add_action('updated_postmeta', array($this,'update_post_meta'), 100, 4); // ajax
  61. add_action('added_postmeta', array($this,'update_post_meta'), 100, 4); // ajax
  62. add_action('delete_postmeta', array($this,'delete_post_meta')); // ajax
  63. //add_filter('get_post_metadata', array($this,'get_post_metadata_filter'), 10, 4);
  64. // filter user taxonomy input
  65. add_filter('pre_post_tax_input', array($this, 'validate_taxonomy_input'));
  66. // Post/page delete actions
  67. add_action('delete_post', array($this,'delete_post_actions'));
  68. add_action('wp_trash_post', array($this,'trash_post_actions'));
  69. add_action('untrashed_post', array($this,'untrashed_post_actions'));
  70. add_filter('posts_join', array($this,'posts_join_filter'));
  71. add_filter('posts_where', array($this,'posts_where_filter'));
  72. add_filter('comment_feed_join', array($this,'comment_feed_join'));
  73. add_filter('comments_clauses', array($this, 'comments_clauses'), 10, 2);
  74. // Allow us to filter the Query before vars before the posts query is being built and executed
  75. add_filter('pre_get_posts', array($this, 'pre_get_posts'));
  76. // show untranslated posts
  77. if(!is_admin() && isset($this->settings['show_untranslated_blog_posts']) &&
  78. $this->settings['show_untranslated_blog_posts'] && $this->get_current_language() != $this->get_default_language()){
  79. add_filter('the_posts', array($this, 'the_posts'));
  80. }
  81. if($pagenow == 'edit.php'){
  82. add_action('admin_footer', array($this,'language_filter'));
  83. }
  84. add_filter('get_pages', array($this, 'exclude_other_language_pages2'));
  85. add_filter('wp_dropdown_pages', array($this, 'wp_dropdown_pages'));
  86. // posts and pages links filters
  87. add_filter('post_link', array($this, 'permalink_filter'),1,2);
  88. add_filter('post_type_link', array($this, 'permalink_filter'),1,2);
  89. add_filter('page_link', array($this, 'permalink_filter'),1,2);
  90. if(version_compare(preg_replace('#-RC[0-9]+(-[0-9]+)?$#', '', $GLOBALS['wp_version']), '3.1', '<')){
  91. add_filter('category_link', array($this, 'category_permalink_filter'),1,2);
  92. add_filter('tag_link', array($this, 'tax_permalink_filter'),1,2);
  93. }
  94. add_filter('term_link', array($this, 'tax_permalink_filter'),1,2);
  95. add_filter('get_comment_link', array($this, 'get_comment_link_filter'));
  96. add_action('create_term', array($this, 'create_term'),1, 2);
  97. add_action('edit_term', array($this, 'create_term'),1, 2);
  98. add_action('delete_term', array($this, 'delete_term'),1,3);
  99. add_action('get_term', array($this, 'get_term_filter'),1,2);
  100. add_filter('get_terms_args', array($this, 'get_terms_args_filter'));
  101. // filters terms by language
  102. if(version_compare($GLOBALS['wp_version'], '3.1', '>=')){
  103. add_filter('terms_clauses', array($this, 'terms_clauses'));
  104. }else{
  105. add_filter('list_terms_exclusions', array($this, 'exclude_other_terms'),1,2);
  106. }
  107. // allow adding terms with the same name in different languages
  108. add_filter("pre_term_name", array($this, 'pre_term_name'), 1, 2);
  109. // allow adding categories with the same name in different languages
  110. add_action('admin_init', array($this, 'pre_save_category'));
  111. // custom hook for adding the language selector to the template
  112. add_action('icl_language_selector', array($this, 'language_selector'));
  113. // front end js
  114. add_action('wp_head', array($this, 'front_end_js'));
  115. add_action('wp_head', array($this,'rtl_fix'));
  116. add_action('admin_print_styles', array($this,'rtl_fix'));
  117. add_action('restrict_manage_posts', array($this, 'restrict_manage_posts'));
  118. add_filter('get_edit_post_link', array($this, 'get_edit_post_link'), 1, 3);
  119. add_filter('get_edit_term_link', array($this, 'get_edit_term_link'), 1, 4);
  120. // short circuit get default category
  121. add_filter('pre_option_default_category', array($this, 'pre_option_default_category'));
  122. add_filter('update_option_default_category', array($this, 'update_option_default_category'), 1, 2);
  123. add_filter('the_category', array($this,'the_category_name_filter'));
  124. add_filter('get_terms', array($this,'get_terms_filter'));
  125. add_filter('get_the_terms', array($this, 'get_the_terms_filter'), 10, 3);
  126. add_filter('single_cat_title', array($this,'the_category_name_filter'));
  127. add_filter('term_links-category', array($this,'the_category_name_filter'));
  128. add_filter('term_links-post_tag', array($this,'the_category_name_filter'));
  129. add_filter('tags_to_edit', array($this,'the_category_name_filter'));
  130. add_filter('single_tag_title', array($this,'the_category_name_filter'));
  131. // adjacent posts links
  132. add_filter('get_previous_post_join', array($this,'get_adjacent_post_join'));
  133. add_filter('get_next_post_join', array($this,'get_adjacent_post_join'));
  134. add_filter('get_previous_post_where', array($this,'get_adjacent_post_where'));
  135. add_filter('get_next_post_where', array($this,'get_adjacent_post_where'));
  136. // feeds links
  137. add_filter('feed_link', array($this,'feed_link'));
  138. // commenting links
  139. add_filter('post_comments_feed_link', array($this,'post_comments_feed_link'));
  140. add_filter('trackback_url', array($this,'trackback_url'));
  141. add_filter('user_trailingslashit', array($this,'user_trailingslashit'),1, 2);
  142. // date based archives
  143. add_filter('year_link', array($this,'archives_link'));
  144. add_filter('month_link', array($this,'archives_link'));
  145. add_filter('day_link', array($this,'archives_link'));
  146. add_filter('getarchives_join', array($this,'getarchives_join'));
  147. add_filter('getarchives_where', array($this,'getarchives_where'));
  148. add_filter('pre_option_home', array($this,'pre_option_home'));
  149. if (!is_admin()) {
  150. add_filter('attachment_link', array($this, 'attachment_link_filter'), 10, 2);
  151. }
  152. // Filter custom type archive link (since WP 3.1)
  153. add_filter('post_type_archive_link', array($this,'post_type_archive_link_filter'), 10, 2);
  154. add_filter('author_link', array($this,'author_link'));
  155. add_filter('wp_unique_post_slug', array($this, 'wp_unique_post_slug'), 100, 5);
  156. add_filter('home_url', array($this, 'home_url'), 1, 4) ;
  157. // language negotiation
  158. add_action('query_vars', array($this,'query_vars'));
  159. //
  160. add_filter('language_attributes', array($this, 'language_attributes'));
  161. add_action('locale', array($this, 'locale'));
  162. if(isset($_GET['____icl_validate_domain'])){ echo '<!--'.get_option('home').'-->'; exit; }
  163. add_filter('pre_option_page_on_front', array($this,'pre_option_page_on_front'));
  164. add_filter('pre_option_page_for_posts', array($this,'pre_option_page_for_posts'));
  165. add_filter('option_sticky_posts', array($this,'option_sticky_posts'));
  166. add_filter('request', array($this,'request_filter'));
  167. add_action('wp_head', array($this,'set_wp_query'));
  168. add_action('show_user_profile', array($this, 'show_user_options'));
  169. add_action('personal_options_update', array($this, 'save_user_options'));
  170. // column with links to translations (or add translation) - low priority
  171. add_action('init', array($this,'configure_custom_column'), 1010); // accommodate Types init@999
  172. // adjust queried categories and tags ids according to the language
  173. if($this->settings['auto_adjust_ids']){
  174. add_action('parse_query', array($this, 'parse_query'));
  175. add_action('wp_list_pages_excludes', array($this, 'adjust_wp_list_pages_excludes'));
  176. if(!is_admin()){
  177. add_filter('get_term', array($this,'get_term_adjust_id'), 1, 1);
  178. add_filter('category_link', array($this,'category_link_adjust_id'), 1, 2);
  179. add_filter('get_terms', array($this,'get_terms_adjust_ids'), 1, 3);
  180. add_filter('get_pages', array($this,'get_pages_adjust_ids'), 1, 2);
  181. }
  182. }
  183. if(!is_admin()){
  184. add_action('wp_head', array($this, 'meta_generator_tag'));
  185. }
  186. require_once ICL_PLUGIN_PATH . '/inc/wp-nav-menus/iclNavMenu.class.php';
  187. $iclNavMenu = new iclNavMenu;
  188. if(is_admin() || defined('XMLRPC_REQUEST') || preg_match('#wp-comments-post\.php$#', $_SERVER['REQUEST_URI'])){
  189. global $iclTranslationManagement, $ICL_Pro_Translation;
  190. $iclTranslationManagement = new TranslationManagement;
  191. $ICL_Pro_Translation = new ICL_Pro_Translation();
  192. }
  193. add_action('wp_login', array($this, 'reset_admin_language_cookie'));
  194. add_action('template_redirect', array($this, 'setup_canonical_urls'), 100);
  195. add_action('init', array($this, '_taxonomy_languages_menu'), 99); //allow hooking in
  196. if($this->settings['seo']['head_langs']){
  197. add_action('wp_head', array($this, 'head_langs'));
  198. }
  199. } //end if the initial language is set - existing_content_language_verified
  200. add_action('wp_dashboard_setup', array($this, 'dashboard_widget_setup'));
  201. if(is_admin() && $pagenow == 'index.php'){
  202. add_action('icl_dashboard_widget_notices', array($this, 'print_translatable_custom_content_status'));
  203. }
  204. add_filter('core_version_check_locale', array($this, 'wp_upgrade_locale'));
  205. if($pagenow == 'post.php' && isset($_REQUEST['action']) && $_REQUEST['action']=='edit' && isset($_GET['post'])){
  206. add_action('init', '_icl_trash_restore_prompt');
  207. }
  208. add_action('init', array($this, 'js_load'), 2); // enqueue scripts - higher priority
  209. }
  210. function init(){
  211. global $wpdb;
  212. $this->get_user_preferences();
  213. // // default value for theme_localization_type OR
  214. // reset theme_localization_type if string translation was on (theme_localization_type was set to 2) and then it was deactivated
  215. /*
  216. if(
  217. !isset($this->settings['theme_localization_type']) ||
  218. isset($this->settings['theme_localization_type']) && $this->settings['theme_localization_type'] == 1 && !defined('WPML_ST_VERSION')
  219. ){
  220. if(!defined('WPML_DOING_UPGRADE')){
  221. $this->settings['theme_localization_type'] = 2;
  222. }
  223. }
  224. */
  225. $this->set_admin_language();
  226. //configure callbacks for plugin menu pages
  227. if(defined('WP_ADMIN') && isset($_GET['page']) && 0 === strpos($_GET['page'],basename(ICL_PLUGIN_PATH).'/')){
  228. add_action('icl_menu_footer', array($this, 'menu_footer'));
  229. }
  230. if($this->settings['existing_content_language_verified']){
  231. if(defined('WP_ADMIN')){
  232. if(isset($_GET['lang'])){
  233. $this->this_lang = rtrim(strip_tags($_GET['lang']),'/');
  234. $al = $this->get_active_languages();
  235. $al['all'] = true;
  236. if(empty($al[$this->this_lang])){
  237. $this->this_lang = $this->get_default_language();
  238. }
  239. // force default language for string translation
  240. // we also make sure it's not saved in the cookie
  241. }elseif(isset($_GET['page']) &&
  242. ((defined('WPML_ST_FOLDER') && $_GET['page'] == WPML_ST_FOLDER . '/menu/string-translation.php') ||
  243. (defined('WPML_TM_FOLDER') && $_GET['page'] == WPML_TM_FOLDER . '/menu/translations-queue.php'))
  244. ){
  245. $this->this_lang = $this->get_default_language();
  246. }elseif(defined('DOING_AJAX')) {
  247. $al = $this->get_active_languages();
  248. if(isset($_POST['lang']) && isset($al[$_POST['lang']])){
  249. $this->this_lang = $_POST['lang'];
  250. }else{
  251. $this->this_lang = $this->get_language_cookie();
  252. }
  253. }elseif($lang = $this->get_admin_language_cookie()){
  254. $this->this_lang = $lang;
  255. }else{
  256. $this->this_lang = $this->get_default_language();
  257. }
  258. if((isset($_GET['admin_bar']) && $_GET['admin_bar']==1) && (!isset($_GET['page']) || !defined('WPML_ST_FOLDER') || $_GET['page'] != WPML_ST_FOLDER . '/menu/string-translation.php')){
  259. $this->set_admin_language_cookie();
  260. }
  261. }else{
  262. $al = $this->get_active_languages();
  263. foreach($al as $l){
  264. $active_languages[] = $l['code'];
  265. }
  266. $active_languages[] = 'all';
  267. $s = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on'?'s':'';
  268. $request = 'http' . $s . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  269. $home = get_option('home');
  270. if($s){
  271. $home = preg_replace('#^http://#', 'https://', $home);
  272. }
  273. $url_parts = parse_url($home);
  274. $blog_path = !empty($url_parts['path'])?$url_parts['path']:'';
  275. switch($this->settings['language_negotiation_type']){
  276. case 1:
  277. $path = str_replace($home,'',$request);
  278. $parts = explode('?', $path);
  279. $path = $parts[0];
  280. $exp = explode('/',trim($path,'/'));
  281. if(in_array($exp[0], $active_languages)){
  282. $this->this_lang = $exp[0];
  283. // before hijiking the SERVER[REQUEST_URI]
  284. // override the canonical_redirect action
  285. // keep a copy of the original request uri
  286. remove_action('template_redirect', 'redirect_canonical');
  287. global $_icl_server_request_uri;
  288. $_icl_server_request_uri = $_SERVER['REQUEST_URI'];
  289. add_action('template_redirect', 'icl_redirect_canonical_wrapper', 11);
  290. function icl_redirect_canonical_wrapper(){
  291. global $_icl_server_request_uri, $wp_query;
  292. $requested_url = ( !empty($_SERVER['HTTPS'] ) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://';
  293. $requested_url .= $_SERVER['HTTP_HOST'];
  294. $requested_url .= $_icl_server_request_uri;
  295. redirect_canonical($requested_url);
  296. /*
  297. if($wp_query->query_vars['error'] == '404'){
  298. $wp_query->is_404 = true;
  299. $template = get_404_template();
  300. include($template);
  301. exit;
  302. }
  303. */
  304. }
  305. //
  306. //deal with situations when template files need to be called directly
  307. add_action('template_redirect', array($this, '_allow_calling_template_file_directly'));
  308. //$_SERVER['REQUEST_URI'] = preg_replace('@^'. $blog_path . '/' . $this->this_lang.'@i', $blog_path ,$_SERVER['REQUEST_URI']);
  309. // Check for special case of www.example.com/fr where the / is missing on the end
  310. $parts = parse_url($_SERVER['REQUEST_URI']);
  311. if(strlen($parts['path']) == 0){
  312. $_SERVER['REQUEST_URI'] = '/' . $_SERVER['REQUEST_URI'];
  313. }
  314. }else{
  315. $this->this_lang = $this->get_default_language();
  316. }
  317. break;
  318. case 2:
  319. $exp = explode('.', $_SERVER['HTTP_HOST']);
  320. $__l = array_search('http' . $s . '://' . $_SERVER['HTTP_HOST'] . $blog_path, $this->settings['language_domains']);
  321. $this->this_lang = $__l?$__l:$this->get_default_language();
  322. if(defined('ICL_USE_MULTIPLE_DOMAIN_LOGIN') && ICL_USE_MULTIPLE_DOMAIN_LOGIN){
  323. include ICL_PLUGIN_PATH . '/modules/multiple-domains-login.php';
  324. }
  325. add_filter('allowed_redirect_hosts', array($this, 'allowed_redirect_hosts'));
  326. break;
  327. case 3:
  328. default:
  329. if(isset($_GET['lang'])){
  330. $this->this_lang = preg_replace("/[^0-9a-zA-Z-]/i", '',strip_tags($_GET['lang']));
  331. // set the language based on the content id - for short links
  332. }elseif(isset($_GET['page_id'])){
  333. $this->this_lang = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_type='post_page' AND element_id=%d", $_GET['page_id']));
  334. }elseif(isset($_GET['p'])){
  335. $post_type = $wpdb->get_var($wpdb->prepare("SELECT post_type FROM {$wpdb->posts} WHERE ID=%d", $_GET['p']));
  336. $this->this_lang = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_type=%s AND element_id=%d",
  337. 'post_' . $post_type, $_GET['p']));
  338. }elseif(isset($_GET['cat_ID'])){
  339. $cat_tax_id = $wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s",
  340. $_GET['cat_ID'], 'category'));
  341. $this->this_lang = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM {$wpdb->prefix}icl_translations
  342. WHERE element_type='tax_category' AND element_id=%d", $cat_tax_id));
  343. }elseif(isset($_GET['tag'])){
  344. $tag_tax_id = $wpdb->get_var($wpdb->prepare("
  345. SELECT x.term_taxonomy_id FROM {$wpdb->term_taxonomy} x JOIN {$wpdb->terms} t ON t.term_id = x.term_id
  346. WHERE t.slug=%s AND x.taxonomy='post_tag'",
  347. $_GET['tag']));
  348. $this->this_lang = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM {$wpdb->prefix}icl_translations
  349. WHERE element_type='tax_post_tag' AND element_id=%d", $tag_tax_id));
  350. }
  351. //
  352. if(!isset($_GET['lang']) && ($this->this_lang && $this->this_lang != $this->get_default_language())){
  353. if(!isset($GLOBALS['wp_rewrite'])){
  354. require_once ABSPATH . WPINC . '/rewrite.php';
  355. $GLOBALS['wp_rewrite'] = new WP_Rewrite();
  356. }
  357. define('ICL_DOING_REDIRECT', true);
  358. if(isset($_GET['page_id'])){
  359. wp_redirect(get_page_link($_GET['page_id']), '301');
  360. exit;
  361. }elseif(isset($_GET['p'])){
  362. wp_redirect(get_permalink($_GET['p']), '301');
  363. exit;
  364. }elseif(isset($_GET['cat_ID'])){
  365. wp_redirect(get_term_link( intval($_GET['cat_ID']), 'category' ));
  366. exit;
  367. }elseif(isset($_GET['tag'])){
  368. wp_redirect(get_term_link( $_GET['tag'], 'post_tag' ));
  369. exit;
  370. }else{
  371. global $wp_taxonomies;
  372. if(isset($this->settings['taxonomies_sync_option'])){
  373. $taxs = array_keys((array)$this->settings['taxonomies_sync_option']);
  374. foreach($taxs as $t){
  375. if(isset($_GET[$t])){
  376. $term_obj = $wpdb->get_row($wpdb->prepare(
  377. "SELECT * FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} x ON t.term_id = x.term_id
  378. WHERE t.slug=%s AND x.taxonomy=%s"
  379. , $_GET[$t], $t));
  380. $term_link = get_term_link( $term_obj, $t );
  381. $term_link = str_replace('&amp;', '&', $term_link); // fix
  382. if($term_link && !is_wp_error($term_link)){
  383. wp_redirect($term_link);
  384. exit;
  385. }
  386. }
  387. }
  388. }
  389. }
  390. }
  391. if(empty($this->this_lang)){
  392. $this->this_lang = $this->get_default_language();
  393. }
  394. }
  395. // allow forcing the current language when it can't be decoded from the URL
  396. $this->this_lang = apply_filters('icl_set_current_language', $this->this_lang);
  397. }
  398. //reorder active language to put 'this_lang' in front
  399. foreach($this->active_languages as $k=>$al){
  400. if($al['code']==$this->this_lang){
  401. unset($this->active_languages[$k]);
  402. $this->active_languages = array_merge(array($k=>$al), $this->active_languages);
  403. }
  404. }
  405. //if($this->settings['language_negotiation_type']==3){
  406. // fix pagenum links for when using the language as a parameter
  407. // add_filter('get_pagenum_link', array($this,'get_pagenum_link_filter'));
  408. //}
  409. // filter some queries
  410. add_filter('query', array($this, 'filter_queries'));
  411. if( $this->settings['language_negotiation_type']==1 && $this->get_current_language()!=$this->get_default_language()){
  412. add_filter('option_rewrite_rules', array($this, 'rewrite_rules_filter'));
  413. }
  414. $this->set_language_cookie();
  415. if(is_admin() &&
  416. (!isset($_GET['page']) || !defined('WPML_ST_FOLDER') || $_GET['page'] != WPML_ST_FOLDER . '/menu/string-translation.php') &&
  417. (!isset($_GET['page']) || !defined('WPML_TM_FOLDER') || $_GET['page'] != WPML_TM_FOLDER . '/menu/translations-queue.php')
  418. ){
  419. if(!$this->is_rtl() && version_compare($GLOBALS['wp_version'], '3.3', '>')){
  420. add_action('admin_notices', 'wpml_set_admin_language_switcher_place', 100);
  421. function wpml_set_admin_language_switcher_place(){
  422. echo '<br clear="all" />';
  423. }
  424. }
  425. add_action('in_admin_header', array($this, 'admin_language_switcher'));
  426. }
  427. if(!is_admin() && defined('DISQUS_VERSION')) include ICL_PLUGIN_PATH . '/modules/disqus.php';
  428. }
  429. if($this->is_rtl()){
  430. $GLOBALS['text_direction'] = 'rtl';
  431. }
  432. // Automatic redirect
  433. if(!is_admin() && !empty($this->settings['automatic_redirect'])){
  434. add_action('template_redirect', array($this, 'automatic_redirect'));
  435. }
  436. if(is_admin() && empty($this->settings['dont_show_help_admin_notice'])){
  437. if(count($this->get_active_languages()) < 2){
  438. add_action('admin_notices', array($this, 'help_admin_notice'));
  439. }
  440. }
  441. $short_v = implode('.', array_slice(explode('.', ICL_SITEPRESS_VERSION), 0, 3));
  442. if(is_admin() && (!isset($this->settings['hide_upgrade_notice']) || $this->settings['hide_upgrade_notice'] != $short_v)){
  443. add_action('admin_notices', array($this, 'upgrade_notice'));
  444. }
  445. if(is_admin() && current_user_can('manage_options')){
  446. if($this->icl_account_configured()) {
  447. add_action('admin_notices', array($this, 'icl_reminders'));
  448. }
  449. }
  450. require ICL_PLUGIN_PATH . '/inc/template-constants.php';
  451. if(defined('WPML_LOAD_API_SUPPORT')){
  452. require ICL_PLUGIN_PATH . '/inc/wpml-api.php';
  453. }
  454. add_action('wp_footer', array($this, 'display_wpml_footer'),20);
  455. if(defined('XMLRPC_REQUEST') && XMLRPC_REQUEST){
  456. add_action('xmlrpc_call', array($this, 'xmlrpc_call_actions'));
  457. add_filter('xmlrpc_methods',array($this, 'xmlrpc_methods'));
  458. }
  459. if(defined('WPML_TM_VERSION') && is_admin()){
  460. require ICL_PLUGIN_PATH . '/inc/quote.php';
  461. }
  462. }
  463. function setup(){
  464. return !empty($this->settings['setup_complete']);
  465. }
  466. function automatic_redirect(){
  467. $save_cookie = false;
  468. if(empty($_COOKIE['_icl_visitor_lang'])){
  469. //No cookie found
  470. $lang = $this->get_current_language();
  471. $langs = @explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
  472. foreach($langs as $lang){
  473. $lang = preg_replace('#q=(.+)$#', '', $lang);
  474. $lang = str_replace('-', '_', $lang); // normalize
  475. if(!in_array($lang, array_keys($this->get_active_languages()))){
  476. $lang = substr($lang, 0, strpos($lang, '_'));
  477. }
  478. if(in_array($lang, array_keys($this->get_active_languages()))){
  479. //'Got lang from browser: %s', $lang
  480. $save_cookie = true;
  481. break;
  482. }
  483. }
  484. }else{
  485. //'Cookie found: %s', $_COOKIE['_icl_visitor_lang']
  486. if($_COOKIE['_icl_visitor_lang'] != $this->get_current_language()){
  487. //'User changed language: %s', $this->get_current_language())
  488. $lang = $this->get_current_language();
  489. $save_cookie = true;
  490. }else{
  491. //'Using cookie lang: %s', $_COOKIE['_icl_visitor_lang']
  492. $lang = $_COOKIE['_icl_visitor_lang'];
  493. }
  494. }
  495. if($save_cookie){
  496. $cookie_domain = defined('COOKIE_DOMAIN') ? COOKIE_DOMAIN : $_SERVER['HTTP_HOST'];
  497. $cookie_path = defined('COOKIEPATH') ? COOKIEPATH : '/';
  498. $s = setcookie('_icl_visitor_lang', $lang, time()+3600 * intval($this->settings['remember_language']), $cookie_path, $cookie_domain);
  499. //'Saving cookie: %s', $lang
  500. }
  501. if($lang != $this->get_current_language()){
  502. //'Doing redirect from %s to %s', $this->get_current_language(), $lang
  503. if($this->settings['automatic_redirect'] == 1){
  504. $args['skip_missing'] = 1;
  505. }else{
  506. $args['skip_missing'] = 0;
  507. }
  508. $languages = $this->get_ls_languages($args);
  509. if(isset($languages[$lang])){
  510. header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
  511. header("Expires: Sat, 16 Aug 1980 05:00:00 GMT"); // Date in the past
  512. if(false !== strpos($_SERVER['HTTP_USER_AGENT'], 'Safari')){
  513. $http_code = 307;
  514. }else{
  515. $http_code = 300;
  516. }
  517. wp_redirect($languages[$lang]['url'], $http_code);
  518. exit;
  519. }
  520. }
  521. //'No redirect needed.'
  522. }
  523. function ajax_setup(){
  524. require ICL_PLUGIN_PATH . '/ajax.php';
  525. }
  526. function configure_custom_column(){
  527. global $pagenow, $wp_post_types;
  528. $pagenow_ = '';
  529. $is_ajax = false;
  530. if($pagenow == 'admin-ajax.php'){
  531. if(
  532. isset($_POST['action']) && $_POST['action']=='inline-save' ||
  533. isset($_GET['action']) && $_GET['action'] == 'fetch-list'
  534. ){
  535. $is_ajax = true;
  536. }
  537. }
  538. if(($pagenow == 'edit.php' || $pagenow_ == 'edit-pages.php' || $is_ajax)){
  539. $post_type = isset($_REQUEST['post_type']) ? $_REQUEST['post_type'] : 'post';
  540. switch($post_type){
  541. case 'post': case 'page':
  542. add_filter('manage_'.$post_type.'s_columns',array($this,'add_posts_management_column'));
  543. if(isset($_GET['post_type']) && $_GET['post_type']=='page'){
  544. add_action('manage_'.$post_type.'s_custom_column',array($this,'add_content_for_posts_management_column'));
  545. }
  546. add_action('manage_posts_custom_column',array($this,'add_content_for_posts_management_column'));
  547. break;
  548. default:
  549. if(in_array($post_type, array_keys($this->get_translatable_documents()))){
  550. add_filter('manage_'.$post_type.'_posts_columns',array($this,'add_posts_management_column'));
  551. if($wp_post_types[$post_type]->hierarchical){
  552. add_action('manage_pages_custom_column',array($this,'add_content_for_posts_management_column'));
  553. add_action('manage_posts_custom_column',array($this,'add_content_for_posts_management_column')); // add this too - for more types plugin
  554. }else{
  555. add_action('manage_posts_custom_column',array($this,'add_content_for_posts_management_column'));
  556. }
  557. }
  558. }
  559. add_action('admin_print_scripts', array($this, '__set_posts_management_column_width'));
  560. }
  561. }
  562. function _taxonomy_languages_menu(){
  563. // tags language selection
  564. global $pagenow, $wpdb;
  565. if($pagenow == 'edit-tags.php'){
  566. // handle case of the tax edit page (after a taxonomy has been added)
  567. // needs to redirect back to
  568. if(isset($_GET['trid']) && isset($_GET['source_lang'])){
  569. $translations = $this->get_element_translations($_GET['trid'], 'tax_' . $_GET['taxonomy']);
  570. if(isset($translations[$_GET['lang']])){
  571. wp_redirect(get_edit_term_link($translations[$_GET['lang']]->term_id, $_GET['taxonomy']));
  572. exit;
  573. }else{
  574. add_action( 'admin_notices', array($this, '_tax_adding') );
  575. }
  576. }
  577. $taxonomy = isset($_GET['taxonomy']) ? $wpdb->escape($_GET['taxonomy']) : 'post_tag';
  578. if($this->is_translated_taxonomy($taxonomy)){
  579. add_action('admin_print_scripts-edit-tags.php', array($this,'js_scripts_tags'));
  580. if($taxonomy == 'category'){
  581. add_action('edit_category_form', array($this, 'edit_term_form'));
  582. }else{
  583. add_action('add_tag_form', array($this, 'edit_term_form'));
  584. add_action('edit_tag_form', array($this, 'edit_term_form'));
  585. }
  586. add_action('admin_footer', array($this,'terms_language_filter'));
  587. add_filter('wp_dropdown_cats', array($this, 'wp_dropdown_cats_select_parent'));
  588. }
  589. }
  590. }
  591. function _tax_adding(){
  592. $translations = $this->get_element_translations($_GET['trid'], 'tax_' . $_GET['taxonomy']);
  593. if(!empty($translations) && isset($translations[$_GET['source_lang']]->name)){
  594. $tax_name = apply_filters('the_category', $translations[$_GET['source_lang']]->name);
  595. echo '<div id="icl_tax_adding_notice" class="updated fade"><p>'. sprintf(__('Adding translation for: %s.', 'sitepress'), $tax_name). '</p></div>';
  596. }
  597. }
  598. function the_posts($posts){
  599. global $wpdb, $wp_query;
  600. $db = debug_backtrace();
  601. $custom_wp_query = isset($db[3]['object']) ? $db[3]['object'] : false;
  602. //exceptions
  603. if(
  604. ($this->get_current_language() == $this->get_default_language()) // original language
  605. || ($wp_query != $custom_wp_query) // called by a custom query
  606. || (!$custom_wp_query->is_posts_page && !$custom_wp_query->is_home) // not the blog posts page
  607. || $wp_query->is_singular //is singular
  608. || !empty($custom_wp_query->query_vars['category__not_in'])
  609. //|| !empty($custom_wp_query->query_vars['category__in'])
  610. //|| !empty($custom_wp_query->query_vars['category__and'])
  611. || !empty($custom_wp_query->query_vars['tag__not_in'])
  612. || !empty($custom_wp_query->query_vars['post__in'])
  613. || !empty($custom_wp_query->query_vars['post__not_in'])
  614. || !empty($custom_wp_query->query_vars['post_parent'])
  615. ){
  616. //$wp_query->query_vars = $this->wp_query->query_vars;
  617. return $posts;
  618. }
  619. // get the posts in the default language instead
  620. $this_lang = $this->this_lang;
  621. $this->this_lang = $this->get_default_language();
  622. remove_filter('the_posts', array($this, 'the_posts'));
  623. $custom_wp_query->query_vars['suppress_filters'] = 0;
  624. if(isset($custom_wp_query->query_vars['pagename']) && !empty($custom_wp_query->query_vars['pagename'])){
  625. if (isset($custom_wp_query->queried_object_id) && !empty($custom_wp_query->queried_object_id)) {
  626. $page_id = $custom_wp_query->queried_object_id;
  627. } else {
  628. // urlencode added for languages that have urlencoded post_name field value
  629. $custom_wp_query->query_vars['pagename'] = urlencode($custom_wp_query->query_vars['pagename']);
  630. $page_id = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_name='{$custom_wp_query->query_vars['pagename']}' AND post_type='page'");
  631. }
  632. if($page_id){
  633. $tr_page_id = icl_object_id($page_id, 'page', false, $this->get_default_language());
  634. if($tr_page_id){
  635. $custom_wp_query->query_vars['pagename'] = $wpdb->get_var("SELECT post_name FROM {$wpdb->posts} WHERE ID={$tr_page_id}");
  636. }
  637. }
  638. }
  639. // look for posts without translations
  640. if($posts){
  641. foreach($posts as $p){
  642. $pids[] = $p->ID;
  643. }
  644. $trids = $wpdb->get_col("
  645. SELECT trid
  646. FROM {$wpdb->prefix}icl_translations
  647. WHERE element_type='post_post' AND element_id IN (".join(',', $pids).") AND language_code = '".$this_lang."'");
  648. if(!empty($trids)){
  649. $posts_not_translated = $wpdb->get_col("
  650. SELECT element_id, COUNT(language_code) AS c
  651. FROM {$wpdb->prefix}icl_translations
  652. WHERE trid IN (".join(',', $trids).") GROUP BY trid HAVING c = 1
  653. ");
  654. if(!empty($posts_not_translated)){
  655. $GLOBALS['__icl_the_posts_posts_not_translated'] = $posts_not_translated;
  656. add_filter('posts_where', array($this, '_posts_untranslated_extra_posts_where'), 99);
  657. }
  658. }
  659. }
  660. //fix page for posts
  661. unset($custom_wp_query->query_vars['page_id']); unset($custom_wp_query->query_vars['p']);
  662. $my_query = new WP_Query($custom_wp_query->query_vars);
  663. add_filter('the_posts', array($this, 'the_posts'));
  664. $this->this_lang = $this_lang;
  665. // create a map of the translated posts
  666. foreach($posts as $post){
  667. $trans_posts[$post->ID] = $post;
  668. }
  669. // loop original posts
  670. foreach($my_query->posts as $k=>$post){ // loop posts in the default language
  671. $trid = $this->get_element_trid($post->ID);
  672. $translations = $this->get_element_translations($trid); // get translations
  673. if(isset($translations[$this->get_current_language()])){ // if there is a translation in the current language
  674. if(isset($trans_posts[$translations[$this->get_current_language()]->element_id])){ //check the map of translated posts
  675. $my_query->posts[$k] = $trans_posts[$translations[$this->get_current_language()]->element_id];
  676. }else{ // check if the translated post exists in the database still
  677. $_post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d AND post_status='publish' LIMIT 1", $translations[$this->get_current_language()]->element_id));
  678. if(!empty($_post)){
  679. $_post = sanitize_post($_post);
  680. $my_query->posts[$k] = $_post;
  681. }else{
  682. $my_query->posts[$k]->original_language = true;
  683. }
  684. }
  685. }else{
  686. $my_query->posts[$k]->original_language = true;
  687. }
  688. }
  689. if($custom_wp_query == $wp_query){
  690. $wp_query->max_num_pages = $my_query->max_num_pages;
  691. }
  692. $posts = $my_query->posts;
  693. unset($GLOBALS['__icl_the_posts_posts_not_translated']);
  694. remove_filter('posts_where', array($this, '_posts_untranslated_extra_posts_where'), 99);
  695. return $posts;
  696. }
  697. function _posts_untranslated_extra_posts_where($where){
  698. global $wpdb;
  699. $where .= ' OR ' . $wpdb->posts . '.ID IN (' . join(',', $GLOBALS['__icl_the_posts_posts_not_translated']) . ')';
  700. return $where;
  701. }
  702. function initialize_cache(){
  703. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  704. $this->icl_translations_cache = new icl_cache();
  705. $this->icl_locale_cache = new icl_cache('locale', true);
  706. $this->icl_flag_cache = new icl_cache('flags', true);
  707. $this->icl_language_name_cache = new icl_cache('language_name', true);
  708. $this->icl_term_taxonomy_cache = new icl_cache();
  709. }
  710. function set_admin_language(){
  711. global $wpdb, $current_user;
  712. if(is_null($current_user) && function_exists('wp_get_current_user')){
  713. $u = wp_get_current_user();
  714. if(isset($u->ID) && $u->ID > 0){
  715. $current_user = $u;
  716. }else{
  717. return $this->get_default_language();
  718. }
  719. }
  720. $active_languages = array_keys($wpdb->get_col("SELECT code FROM {$wpdb->prefix}icl_languages WHERE active=1")); //don't use method get_active_language()
  721. if(!empty($current_user->data->ID)){
  722. $this->admin_language = $this->get_user_admin_language($current_user->data->ID);
  723. }
  724. if($this->admin_language != '' && !in_array($this->admin_language, $active_languages)){
  725. delete_user_meta($current_user->data->ID,'icl_admin_language');
  726. }
  727. if(empty($this->settings['admin_default_language']) || !in_array($this->settings['admin_default_language'], $active_languages)){
  728. $this->settings['admin_default_language'] = '_default_';
  729. $this->save_settings();
  730. }
  731. if(!$this->admin_language){
  732. $this->admin_language = $this->settings['admin_default_language'];
  733. }
  734. if($this->admin_language == '_default_' && $this->get_default_language()){
  735. $this->admin_language = $this->get_default_language();
  736. }
  737. }
  738. function get_admin_language(){
  739. return $this->admin_language;
  740. }
  741. function get_user_admin_language($user_id) {
  742. static $lang = array();
  743. if (!isset($lang[$user_id])) {
  744. $lang[$user_id] = get_user_meta($user_id,'icl_admin_language',true);
  745. if(empty($lang[$user_id])){
  746. if(isset($this->settings['admin_default_language'])){
  747. $lang[$user_id] = $this->settings['admin_default_language'];
  748. }
  749. if(empty($lang[$user_id]) || '_default_' == $lang[$user_id]){
  750. $lang[$user_id] = $this->get_admin_language();
  751. }
  752. }
  753. }
  754. return $lang[$user_id];
  755. }
  756. function administration_menu(){
  757. if (1 < count($this->get_active_languages())) {
  758. $main_page = apply_filters('icl_menu_main_page', basename(ICL_PLUGIN_PATH).'/menu/languages.php');
  759. add_menu_page(__('WPML','sitepress'), __('WPML','sitepress'), 'manage_options',
  760. $main_page, null, ICL_PLUGIN_URL . '/res/img/icon16.png');
  761. do_action('icl_wpml_top_menu_added');
  762. add_submenu_page($main_page,
  763. __('Languages','sitepress'), __('Languages','sitepress'),
  764. 'manage_options', basename(ICL_PLUGIN_PATH).'/menu/languages.php');
  765. add_submenu_page($main_page,
  766. __('Theme and plugins localization','sitepress'), __('Theme and plugins localization','sitepress'),
  767. 'manage_options', basename(ICL_PLUGIN_PATH).'/menu/theme-localization.php');
  768. if(!defined('WPML_TM_VERSION')){
  769. add_submenu_page($main_page,
  770. __('Translation options','sitepress'), __('Translation options','sitepress'),
  771. 'manage_options', basename(ICL_PLUGIN_PATH).'/menu/translation-options.php');
  772. }
  773. /*
  774. add_submenu_page($main_page,
  775. __('Comments translation','sitepress'), __('Comments translation','sitepress'),
  776. 'manage_options', basename(ICL_PLUGIN_PATH).'/menu/comments-translation.php');
  777. */
  778. } else {
  779. $main_page = basename(ICL_PLUGIN_PATH).'/menu/languages.php';
  780. add_menu_page(__('WPML','sitepress'), __('WPML','sitepress'), 'manage_options',
  781. $main_page,null, ICL_PLUGIN_URL . '/res/img/icon16.png');
  782. add_submenu_page($main_page,
  783. __('Languages','sitepress'), __('Languages','sitepress'),
  784. 'manage_options', basename(ICL_PLUGIN_PATH).'/menu/languages.php');
  785. }
  786. if(isset($_GET['page']) && $_GET['page'] == basename(ICL_PLUGIN_PATH).'/menu/troubleshooting.php'){
  787. add_submenu_page($main_page,
  788. __('Troubleshooting','sitepress'), __('Troubleshooting','sitepress'),
  789. 'manage_options', basename(ICL_PLUGIN_PATH).'/menu/troubleshooting.php');
  790. }
  791. //$alert = '&nbsp;<img width="12" height="12" style="margin-bottom:-2px;" src="'.ICL_PLUGIN_URL.'/res/img/alert.png" />';
  792. add_submenu_page($main_page,
  793. __('Support','sitepress'), __('Support','sitepress'), 'manage_options', ICL_PLUGIN_FOLDER . '/menu/support.php');
  794. }
  795. function save_settings($settings=null){
  796. if(!is_null($settings)){
  797. foreach($settings as $k=>$v){
  798. if(is_array($v)){
  799. foreach($v as $k2=>$v2){
  800. $this->settings[$k][$k2] = $v2;
  801. }
  802. }else{
  803. $this->settings[$k] = $v;
  804. }
  805. }
  806. }
  807. if(!empty($this->settings)){
  808. update_option('icl_sitepress_settings', $this->settings);
  809. }
  810. do_action('icl_save_settings', $settings);
  811. }
  812. function get_settings(){
  813. return $this->settings;
  814. }
  815. function get_option($option_name){
  816. return isset($this->settings[$option_name]) ? $this->settings[$option_name] : null;
  817. }
  818. function verify_settings(){
  819. $default_settings = array(
  820. 'interview_translators' => 1,
  821. 'existing_content_language_verified' => 0,
  822. 'language_negotiation_type' => 3,
  823. 'theme_localization_type' => 1,
  824. 'icl_lso_header' => 0,
  825. 'icl_lso_link_empty' => 0,
  826. 'icl_lso_flags' => 0,
  827. 'icl_lso_native_lang' => 1,
  828. 'icl_lso_display_lang' => 1,
  829. 'sync_page_ordering' => 1,
  830. 'sync_page_parent' => 1,
  831. 'sync_page_template' => 1,
  832. 'sync_ping_status' => 1,
  833. 'sync_comment_status' => 1,
  834. 'sync_sticky_flag' => 1,
  835. 'sync_private_flag' => 1,
  836. 'sync_post_format' => 1,
  837. 'sync_delete' => 0,
  838. 'sync_post_taxonomies' => 1,
  839. 'sync_post_date' => 0,
  840. 'sync_taxonomy_parents' => 0,
  841. 'translation_pickup_method' => 0,
  842. 'notify_complete' => 1,
  843. 'translated_document_status' => 1,
  844. 'remote_management' => 0,
  845. 'auto_adjust_ids' => 1,
  846. 'alert_delay' => 0,
  847. 'promote_wpml' => 0,
  848. 'troubleshooting_options' => array('http_communication' => 1),
  849. 'automatic_redirect' => 0,
  850. 'remember_language' => 24,
  851. 'icl_lang_sel_type' => 'dropdown',
  852. 'icl_widget_title_show' => 1,
  853. 'translated_document_page_url' => 'auto-generate',
  854. 'sync_comments_on_duplicates ' => 0,
  855. 'seo' => array('head_langs' => 1)
  856. );
  857. //congigured for three levels
  858. $update_settings = false;
  859. foreach($default_settings as $key => $value){
  860. if(is_array($value)){
  861. foreach($value as $k2 => $v2){
  862. if(is_array($v2)){
  863. foreach($v2 as $k3 => $v3){
  864. if(!isset($this->settings[$key][$k2][$k3])){
  865. $this->settings[$key][$k2][$k3] = $v3;
  866. $update_settings = true;
  867. }
  868. }
  869. }else{
  870. if(!isset($this->settings[$key][$k2])){
  871. $this->settings[$key][$k2] = $v2;
  872. $update_settings = true;
  873. }
  874. }
  875. }
  876. }else{
  877. if(!isset($this->settings[$key])){
  878. $this->settings[$key] = $value;
  879. $update_settings = true;
  880. }
  881. }
  882. }
  883. if($update_settings){
  884. $this->save_settings();
  885. }
  886. }
  887. function _validate_language_per_directory($language_code){
  888. if(!class_exists('WP_Http')) include_once ABSPATH . WPINC . '/class-http.php';
  889. $client = new WP_Http();
  890. if(false === @strpos($_POST['url'],'?')){$url_glue='?';}else{$url_glue='&';}
  891. $response = $client->request(get_option('home') . '/' . $language_code .'/' . $url_glue . '____icl_validate_domain=1', array('timeout'=>15, 'decompress'=>false));
  892. return (!is_wp_error($response) && ($response['response']['code']=='200') && ($response['body'] == '<!--'.get_option('home').'-->'));
  893. }
  894. function save_language_pairs() {
  895. // clear existing languages
  896. $lang_pairs = $this->settings['language_pairs'];
  897. if (is_array($lang_pairs)) {
  898. foreach ($lang_pairs as $from => $to) {
  899. $lang_pairs[$from] = array();
  900. }
  901. }
  902. // get the from languages
  903. $from_languages = array();
  904. foreach($_POST as $k=>$v){
  905. if(0 === strpos($k,'icl_lng_from_')){
  906. $f = str_replace('icl_lng_from_','',$k);
  907. $from_languages[] = $f;
  908. }
  909. }
  910. foreach($_POST as $k=>$v){
  911. if(0 !== strpos($k,'icl_lng_')) continue;
  912. if(0 === strpos($k,'icl_lng_to')){
  913. $t = str_replace('icl_lng_to_','',$k);
  914. $exp = explode('_',$t);
  915. if (in_array($exp[0], $from_languages)){
  916. $lang_pairs[$exp[0]][$exp[1]] = 1;
  917. }
  918. }
  919. }
  920. $iclsettings['language_pairs'] = $lang_pairs;
  921. $this->save_settings($iclsettings);
  922. }
  923. function get_active_languages($refresh = false){
  924. global $wpdb;
  925. if($refresh || !$this->active_languages){
  926. if(defined('WP_ADMIN') && $this->admin_language){
  927. $in_language = $this->admin_language;
  928. }else{
  929. $in_language = $this->get_current_language()?$this->get_current_language():$this->get_default_language();
  930. }
  931. if (isset($this->icl_language_name_cache)) {
  932. $res = $this->icl_language_name_cache->get('in_language_'.$in_language);
  933. } else {
  934. $res = null;
  935. }
  936. if (!$res || !is_array($res)) {
  937. $res = $wpdb->get_results("
  938. SELECT l.id, code, english_name, active, lt.name AS display_name, l.encode_url
  939. FROM {$wpdb->prefix}icl_languages l
  940. JOIN {$wpdb->prefix}icl_languages_translations lt ON l.code=lt.language_code
  941. WHERE
  942. active=1 AND lt.display_language_code = '{$in_language}'
  943. ORDER BY major DESC, english_name ASC", ARRAY_A);
  944. if (isset($this->icl_language_name_cache)) {
  945. $this->icl_language_name_cache->set('in_language_'.$in_language, $res);
  946. }
  947. }
  948. $languages = array();
  949. if($res){
  950. foreach($res as $r){
  951. $languages[$r['code']] = $r;
  952. }
  953. }
  954. if (isset($this->icl_language_name_cache)) {
  955. $res = $this->icl_language_name_cache->get('languages');
  956. } else {
  957. $res = null;
  958. }
  959. if (!$res) {
  960. $res = $wpdb->get_results("
  961. SELECT language_code, name
  962. FROM {$wpdb->prefix}icl_languages_translations
  963. WHERE language_code IN ('".join("','",array_keys($languages))."') AND language_code = display_language_code
  964. ");
  965. if (isset($this->icl_language_name_cache)) {
  966. $this->icl_language_name_cache->set('languages', $res);
  967. }
  968. }
  969. foreach($res as $row){
  970. $languages[$row->language_code]['native_name'] = $row->name;
  971. }
  972. $this->active_languages = $languages;
  973. }
  974. // hide languages for front end
  975. global $current_user;
  976. get_currentuserinfo();
  977. if(!is_admin() && !empty($this->settings['hidden_languages']) && is_array($this->settings['hidden_languages'])){
  978. if(empty($current_user->data) || !get_user_meta($current_user->data->ID, 'icl_show_hidden_languages', true)){
  979. foreach($this->settings['hidden_languages'] as $l){
  980. unset($this->active_languages[$l]);
  981. }
  982. }
  983. }
  984. return $this->active_languages;
  985. }
  986. function set_active_languages($arr){
  987. global $wpdb;
  988. if(!empty($arr)){
  989. foreach($arr as $code){
  990. $tmp[] = mysql_real_escape_string(trim($code));
  991. }
  992. // set the locale
  993. $current_active_languages = (array)$wpdb->get_col("SELECT code FROM {$wpdb->prefix}icl_languages WHERE active = 1");
  994. $new_languages = array_diff($tmp, $current_active_languages);
  995. if(!empty($new_languages)){
  996. foreach($new_languages as $code){
  997. $default_locale = $wpdb->get_var("SELECT default_locale FROM {$wpdb->prefix}icl_languages WHERE code='{$code}'");
  998. if($default_locale){
  999. if($wpdb->get_var("SELECT code FROM {$wpdb->prefix}icl_locale_map WHERE code='{$code}'")){
  1000. $wpdb->update($wpdb->prefix.'icl_locale_map', array('locale'=>$default_locale), array('code'=>$code));
  1001. }else{
  1002. $wpdb->insert($wpdb->prefix.'icl_locale_map', array('code'=>$code, 'locale'=>$default_locale));
  1003. }
  1004. }
  1005. }
  1006. }
  1007. $codes = '(\'' . join('\',\'',$tmp) . '\')';
  1008. $wpdb->update($wpdb->prefix.'icl_languages', array('active'=>0), array('active'=>'1'));
  1009. $wpdb->query("UPDATE {$wpdb->prefix}icl_languages SET active=1 WHERE code IN {$codes}");
  1010. $this->icl_language_name_cache->clear();
  1011. }
  1012. $res = $wpdb->get_results("
  1013. SELECT code, english_name, active, lt.name AS display_name
  1014. FROM {$wpdb->prefix}icl_languages l
  1015. JOIN {$wpdb->prefix}icl_languages_translations lt ON l.code=lt.language_code
  1016. WHERE
  1017. active=1 AND lt.display_language_code = '{$this->get_default_language()}'
  1018. ORDER BY major DESC, english_name ASC", ARRAY_A);
  1019. $languages = array();
  1020. foreach($res as $r){
  1021. $languages[] = $r;
  1022. }
  1023. $this->active_languages = $languages;
  1024. return true;
  1025. }
  1026. function get_languages($lang=false){
  1027. global $wpdb;
  1028. if(!$lang){
  1029. $lang = $this->get_default_language();
  1030. }
  1031. $res = $wpdb->get_results("
  1032. SELECT
  1033. code, english_name, major, active, default_locale, lt.name AS display_name
  1034. FROM {$wpdb->prefix}icl_languages l
  1035. JOIN {$wpdb->prefix}icl_languages_translations lt ON l.code=lt.language_code
  1036. WHERE lt.display_language_code = '{$lang}'
  1037. ORDER BY major DESC, english_name ASC", ARRAY_A);
  1038. $languages = array();
  1039. foreach((array)$res as $r){
  1040. $languages[] = $r;
  1041. }
  1042. return $languages;
  1043. }
  1044. function get_language_details($code){
  1045. global $wpdb;
  1046. if(defined('WP_ADMIN')){
  1047. $dcode = $this->admin_language;
  1048. }else{
  1049. $dcode = $code;
  1050. }
  1051. if (isset($this->icl_language_name_cache)){
  1052. $details = $this->icl_language_name_cache->get('language_details_'.$code.$dcode);
  1053. } else {
  1054. $details = null;
  1055. }
  1056. if (!$details){
  1057. $details = $wpdb->get_row("
  1058. SELECT
  1059. code, english_name, major, active, lt.name AS display_name
  1060. FROM {$wpdb->prefix}icl_languages l
  1061. JOIN {$wpdb->prefix}icl_languages_translations lt ON l.code=lt.language_code
  1062. WHERE lt.display_language_code = '{$dcode}' AND code='{$code}'
  1063. ORDER BY major DESC, english_name ASC", ARRAY_A);
  1064. if (isset($this->icl_language_name_cache)){
  1065. $this->icl_language_name_cache->set('language_details_'.$code.$dcode, $details);
  1066. }
  1067. }
  1068. return $details;
  1069. }
  1070. function get_language_code($english_name){
  1071. global $wpdb;
  1072. $code = $wpdb->get_row("
  1073. SELECT
  1074. code
  1075. FROM {$wpdb->prefix}icl_languages
  1076. WHERE english_name = '{$english_name}'", ARRAY_A);
  1077. return $code['code'];
  1078. }
  1079. function get_icl_translator_status(&$iclsettings, $res = NULL){
  1080. if ($res == NULL) {
  1081. // check what languages we have translators for.
  1082. require_once ICL_PLUGIN_PATH . '/lib/Snoopy.class.php';
  1083. require_once ICL_PLUGIN_PATH . '/lib/xml2array.php';
  1084. require_once ICL_PLUGIN_PATH . '/lib/icl_api.php';
  1085. $icl_query = false;
  1086. if (empty($iclsettings['site_id'])) {
  1087. // Must be for support
  1088. if(!empty($iclsettings['support_site_id'])){
  1089. $icl_query = new ICanLocalizeQuery($iclsettings['support_site_id'], $iclsettings['support_access_key']);
  1090. }
  1091. } else {
  1092. $icl_query = new ICanLocalizeQuery($iclsettings['site_id'], $iclsettings['access_key']);
  1093. }
  1094. if($icl_query === false) return;
  1095. $res = $icl_query->get_website_details();
  1096. }
  1097. if(isset($res['translation_languages']['translation_language'])){
  1098. // reset $this->settings['icl_lang_status']
  1099. $iclsettings['icl_lang_status'] = array();
  1100. $translation_languages = $res['translation_languages']['translation_language'];
  1101. if(!isset($translation_languages[0])){
  1102. $buf = $translation_languages;
  1103. $translation_languages = array(0 => $buf);
  1104. }
  1105. foreach($translation_languages as $lang){
  1106. $translators = $_tr = array();
  1107. $max_rate = false;
  1108. if(isset($lang['translators']) && !empty($lang['translators'])){
  1109. if(!isset($lang['translators']['translator'][0])){
  1110. $_tr[0] = $lang['translators']['translator'];
  1111. }else{
  1112. $_tr = $lang['translators']['translator'];
  1113. }
  1114. foreach($_tr as $t){
  1115. if($max_rate === false || $t['attr']['amount'] > $max_rate){
  1116. $max_rate = $t['attr']['amount'];
  1117. }
  1118. $translators[] = array('id'=>$t['attr']['id'], 'nickname'=>$t['attr']['nickname'], 'contract_id' => $t['attr']['contract_id']);
  1119. }
  1120. }
  1121. $target[] = array(
  1122. 'from' => $this->get_language_code(ICL_Pro_Translation::server_languages_map($lang['attr']['from_language_name'], true)),
  1123. 'to' => $this->get_language_code(ICL_Pro_Translation::server_languages_map($lang['attr']['to_language_name'], true)),
  1124. 'have_translators' => $lang['attr']['have_translators'],
  1125. 'available_translators' => $lang['attr']['available_translators'],
  1126. 'applications' => $lang['attr']['applications'],
  1127. 'contract_id' => $lang['attr']['contract_id'],
  1128. 'id' => $lang['attr']['id'],
  1129. 'translators' => $translators,
  1130. 'max_rate' => $max_rate
  1131. );
  1132. }
  1133. $iclsettings['icl_lang_status'] = $target;
  1134. }
  1135. if(isset($res['client']['attr'])){
  1136. $iclsettings['icl_balance'] = $res['client']['attr']['balance'];
  1137. $iclsettings['icl_anonymous_user'] = $res['client']['attr']['anon'];
  1138. }
  1139. if(isset($res['html_status']['value'])){
  1140. $iclsettings['icl_html_status'] = html_entity_decode($res['html_status']['value']);
  1141. $iclsettings['icl_html_status'] = preg_replace_callback('#<a([^>]*)href="([^"]+)"([^>]*)>#i', create_function(
  1142. '$matches',
  1143. 'global $sitepress; return $sitepress->create_icl_popup_link($matches[2]);'
  1144. ) ,$iclsettings['icl_html_status']);
  1145. }
  1146. if(isset($res['translators_management_info']['value'])){
  1147. $iclsettings['translators_management_info'] = html_entity_decode($res['translators_management_info']['value']);
  1148. $iclsettings['translators_management_info'] = preg_replace_callback('#<a([^>]*)href="([^"]+)"([^>]*)>#i', create_function(
  1149. '$matches',
  1150. 'global $sitepress; return $sitepress->create_icl_popup_link($matches[2], array(\'unload_cb\'=>\'icl_thickbox_refresh\'));'
  1151. ) ,$iclsettings['translators_management_info']);
  1152. }
  1153. $iclsettings['icl_support_ticket_id'] = @intval($res['attr']['support_ticket_id']);
  1154. }
  1155. function get_language_status_text($from_lang, $to_lang, $popclose_cb = false) {
  1156. $popargs = array('title'=>'ICanLocalize');
  1157. if($popclose_cb){
  1158. $popargs['unload_cb'] = $popclose_cb;
  1159. }
  1160. $lang_status = !empty($this->settings['icl_lang_status']) ? $this->settings['icl_lang_status'] : array();
  1161. $response = '';
  1162. foreach ($lang_status as $lang) {
  1163. if ($from_lang == $lang['from'] && $to_lang == $lang['to']) {
  1164. if (isset($lang['available_translators'])) {
  1165. if (!$lang['available_translators']) {
  1166. if ($this->settings['icl_support_ticket_id'] == '') {
  1167. // No translators available on icanlocalize for this language pair.
  1168. $response = sprintf(__('- (No translators available - please %sprovide more information about your site%s)', 'sitepress'),
  1169. $this->create_icl_popup_link(ICL_API_ENDPOINT. '/websites/' . $this->settings['site_id'] . '/explain?after=refresh_langs',
  1170. $popargs),
  1171. '</a>');
  1172. } else {
  1173. $response = sprintf(__('- (No translators available - %scheck progress%s)', 'sitepress'),
  1174. $this->create_icl_popup_link(ICL_API_ENDPOINT. '/support/show/' . $this->settings['icl_support_ticket_id'] . '?after=refresh_langs',
  1175. $popargs),
  1176. '</a>');
  1177. }
  1178. } else if (!$lang['applications']) {
  1179. // No translators have applied for this language pair.
  1180. $popargs['class'] = 'icl_hot_link';
  1181. $response = ' | ' . $this->create_icl_popup_link("@select-translators;{$from_lang};{$to_lang}@", $popargs) .
  1182. __('Select translators', 'sitepress') . '</a>';
  1183. } else if (!$lang['have_translators']) {
  1184. // translators have applied but none selected yet
  1185. $popargs['class'] = 'icl_hot_link';
  1186. $response = ' | ' . $this->create_icl_popup_link("@select-translators;{$from_lang};{$to_lang}@", $popargs) . __('Select translators', 'sitepress') . '</a>';
  1187. } else {
  1188. // there are translators ready to translate
  1189. $translators = array();
  1190. if(is_array($lang['translators'])){
  1191. foreach($lang['translators'] as $translator){
  1192. $link = $this->create_icl_popup_link(ICL_API_ENDPOINT. '/websites/' . $this->settings['site_id'] . '/website_translation_offers/' .
  1193. $lang['id'] . '/website_translation_contracts/' . $translator['contract_id'], $popargs);
  1194. $translators[] = $link . esc_html($translator['nickname']) . '</a>';
  1195. }
  1196. }
  1197. $response = ' | ' . $this->create_icl_popup_link("@select-translators;{$from_lang};{$to_lang}@", $popargs) . __('Select translators', 'sitepress') . '</a>';
  1198. $response .= ' | ' . sprintf(__('Communicate with %s', 'sitepress'), join(', ', $translators));
  1199. }
  1200. return $response;
  1201. }
  1202. break;
  1203. }
  1204. }
  1205. $popargs['class'] = 'icl_hot_link';
  1206. $response = ' | ' . $this->create_icl_popup_link("@select-translators;{$from_lang};{$to_lang}@", $popargs) . __('Select translators', 'sitepress') . '</a>';
  1207. // no status found
  1208. return $response;
  1209. }
  1210. function are_waiting_for_translators($from_lang) {
  1211. $lang_status = $this->settings['icl_lang_status'];
  1212. if ($lang_status && $this->icl_account_configured()) {
  1213. foreach ($lang_status as $lang) {
  1214. if ($from_lang == $lang['from']) {
  1215. if (isset($lang['available_translators'])) {
  1216. if ($lang['available_translators'] && !$lang['applications']) {
  1217. return true;
  1218. }
  1219. }
  1220. }
  1221. }
  1222. }
  1223. return false;
  1224. }
  1225. function get_default_language(){
  1226. return isset($this->settings['default_language']) ? $this->settings['default_language'] : false;
  1227. }
  1228. function get_current_language(){
  1229. return apply_filters('icl_current_language' , $this->this_lang);
  1230. }
  1231. function switch_lang($code = null, $cookie_lang = false){
  1232. static $original_language, $original_language_cookie;
  1233. if(is_null($original_language)) $original_language = $this->get_current_language();
  1234. if(is_null($code)){
  1235. $this->this_lang = $original_language;
  1236. $this->admin_language = $original_language;
  1237. // restore cookie language if case
  1238. if(!empty($original_language_cookie)){
  1239. $_COOKIE['_icl_current_language'] = $original_language_cookie;
  1240. $original_language_cookie = false;
  1241. }
  1242. }else{
  1243. if(in_array($code, array_keys($this->get_active_languages()))){
  1244. $original_language = $this->get_current_language(); // save current language
  1245. $this->this_lang = $code;
  1246. $this->admin_language = $code;
  1247. }
  1248. // override cookie language
  1249. if($cookie_lang){
  1250. $original_language_cookie = $this->get_language_cookie();
  1251. $_COOKIE['_icl_current_language'] = $code;
  1252. }
  1253. }
  1254. }
  1255. function set_default_language($code){
  1256. global $wpdb;
  1257. $iclsettings['default_language'] = $code;
  1258. $this->save_settings($iclsettings);
  1259. // change WP locale
  1260. $locale = $this->get_locale($code);
  1261. if($locale){
  1262. update_option('WPLANG', $locale);
  1263. }
  1264. if($code != 'en' && !file_exists(ABSPATH . LANGDIR . '/' . $locale . '.mo')){
  1265. return 1; //locale not installed
  1266. }
  1267. return true;
  1268. }
  1269. function get_icl_translation_enabled($lang=null, $langto=null){
  1270. if(!is_null($lang)){
  1271. if(!is_null($langto)){
  1272. return $this->settings['language_pairs'][$lang][$langto];
  1273. }else{
  1274. return !empty($this->settings['language_pairs'][$lang]);
  1275. }
  1276. }else{
  1277. return isset($this->settings['enable_icl_translations']) ? $this->settings['enable_icl_translations'] : false;
  1278. }
  1279. }
  1280. function set_icl_translation_enabled(){
  1281. $iclsettings['translation_enabled'] = true;
  1282. $this->save_settings($iclsettings);
  1283. }
  1284. function icl_account_reqs(){
  1285. $errors = array();
  1286. if(!$this->get_icl_translation_enabled()){
  1287. $errors[] = __('Professional translation not enabled', 'sitepress');
  1288. }
  1289. return $errors;
  1290. }
  1291. function icl_account_configured(){
  1292. return isset($this->settings['site_id']) && $this->settings['site_id'] && isset($this->settings['access_key']) && $this->settings['access_key'];
  1293. }
  1294. function icl_support_configured(){
  1295. return isset($this->settings['support_site_id']) && isset($this->settings['support_access_key'])
  1296. && $this->settings['support_site_id'] && $this->settings['support_access_key'];
  1297. }
  1298. function reminders_popup(){
  1299. include ICL_PLUGIN_PATH . '/modules/icl-translation/icl-reminder-popup.php';
  1300. exit;
  1301. }
  1302. function create_icl_popup_link($link, $args = array(), $just_url = false, $support_mode = FALSE) {
  1303. // defaults
  1304. $defaults = array(
  1305. 'title' => null,
  1306. 'class' => '',
  1307. 'id' => '',
  1308. 'ar' => 0, // auto_resize
  1309. 'unload_cb' => false, // onunload callback
  1310. );
  1311. extract($defaults);
  1312. extract($args, EXTR_OVERWRITE);
  1313. if(!empty($ar)){
  1314. $auto_resize = '&amp;auto_resize=1';
  1315. }else{
  1316. $auto_resize = '';
  1317. }
  1318. $unload_cb = isset($unload_cb) ? '&amp;unload_cb=' . $unload_cb : '';
  1319. $url_glue = false !== strpos($link,'?') ? '&' : '?';
  1320. $link .= $url_glue . 'compact=1';
  1321. if (isset($this->settings['access_key']) || isset($this->settings['support_access_key'])){
  1322. if ($support_mode && isset($this->settings['support_access_key'])) {
  1323. $link .= '&accesskey=' . $this->settings['support_access_key'];
  1324. } elseif (isset($this->settings['access_key'])) {
  1325. $link .= '&accesskey=' . $this->settings['access_key'];
  1326. }
  1327. }
  1328. if (!empty($id)) {
  1329. $id = ' id="' . $id . '"';
  1330. }
  1331. if (isset($title) && !$just_url) {
  1332. return '<a class="icl_thickbox ' . $class . '" title="' . $title . '" href="admin.php?page='.ICL_PLUGIN_FOLDER .
  1333. "/menu/languages.php&amp;icl_action=reminder_popup{$auto_resize}{$unload_cb}&amp;target=" . urlencode($link) .'"' . $id . '>';
  1334. } else if (!$just_url) {
  1335. return '<a class="icl_thickbox ' . $class . '" href="admin.php?page='.ICL_PLUGIN_FOLDER .
  1336. "/menu/languages.php&amp;icl_action=reminder_popup{$auto_resize}{$unload_cb}&amp;target=" . urlencode($link) .'"' . $id . '>';
  1337. } else {
  1338. return 'admin.php?page='.ICL_PLUGIN_FOLDER . "/menu/languages.php&amp;icl_action=reminder_popup{$auto_resize}{$unload_cb}&amp;target=" . urlencode($link);
  1339. }
  1340. }
  1341. function js_scripts_setup(){
  1342. global $pagenow, $wpdb;
  1343. if(isset($_GET['page'])){
  1344. $page = basename($_GET['page']);
  1345. $page_basename = str_replace('.php','',$page);
  1346. }else{
  1347. $page_basename = false;
  1348. }
  1349. ?>
  1350. <script type="text/javascript">
  1351. // <![CDATA[
  1352. <?php if(defined('FORCE_SSL_ADMIN') && FORCE_SSL_ADMIN): ?>
  1353. var icl_ajx_url = '<?php echo str_replace('http://', 'https://', rtrim(get_option('siteurl'),'/')) . '/wp-admin/' ?>admin.php?page=<?php echo ICL_PLUGIN_FOLDER ?>/menu/languages.php';
  1354. <?php else: ?>
  1355. var icl_ajx_url = '<?php echo rtrim(get_option('siteurl'),'/') . '/wp-admin/' ?>admin.php?page=<?php echo ICL_PLUGIN_FOLDER ?>/menu/languages.php';
  1356. <?php endif; ?>
  1357. var icl_ajx_saved = '<?php echo icl_js_escape( __('Data saved','sitepress')); ?>';
  1358. var icl_ajx_error = '<?php echo icl_js_escape( __('Error: data not saved','sitepress')); ?>';
  1359. var icl_default_mark = '<?php echo icl_js_escape(__('default','sitepress')); ?>';
  1360. var icl_this_lang = '<?php echo $this->this_lang ?>';
  1361. var icl_ajxloaderimg_src = '<?php echo ICL_PLUGIN_URL ?>/res/img/ajax-loader.gif';
  1362. var icl_cat_adder_msg = '<?php echo icl_js_escape(sprintf(__('To add categories that already exist in other languages go to the <a%s>category management page</a>','sitepress'), ' href="'.admin_url('edit-tags.php?taxonomy=category').'"'));?>';
  1363. // ]]>
  1364. <?php if(empty($this->settings['ajx_health_checked'])): ?>
  1365. addLoadEvent(function(){
  1366. jQuery.ajax({type: "POST",url: icl_ajx_url,data: "icl_ajx_action=health_check", error: function(msg){
  1367. if(jQuery('#icl_initial_language').length){
  1368. jQuery('#icl_initial_language input').attr('disabled', 'disabled');
  1369. }
  1370. jQuery('.wrap').prepend('<div class="error"><p><?php
  1371. echo icl_js_escape(sprintf(__("WPML can't run normally. There is an installation or server configuration problem. %sShow details%s",'sitepress'),
  1372. '<a href="#" onclick="jQuery(this).parent().next().slideToggle()">', '</a>'));
  1373. ?></p><p style="display:none"><?php echo icl_js_escape(__('AJAX Error:', 'sitepress'))?> ' + msg.statusText + ' ['+msg.status+']<br />URL:'+ icl_ajx_url +'</p></div>');
  1374. }});
  1375. });
  1376. <?php endif; ?>
  1377. </script>
  1378. <?php
  1379. if('options-reading.php' == $pagenow ){
  1380. list($warn_home, $warn_posts) = $this->verify_home_and_blog_pages_translations();
  1381. if($warn_home || $warn_posts){ ?>
  1382. <script type="text/javascript">
  1383. addLoadEvent(function(){
  1384. jQuery('input[name="show_on_front"]').parent().parent().parent().parent().append('<?php echo str_replace("'","\\'",$warn_home . $warn_posts); ?>');
  1385. });
  1386. </script>
  1387. <?php }
  1388. }
  1389. // display correct links on the posts by status break down
  1390. // also fix links to category and tag pages
  1391. if( ('edit.php' == $pagenow || 'edit-pages.php' == $pagenow || 'categories.php' == $pagenow || 'edit-tags.php' == $pagenow)
  1392. && $this->get_current_language() != $this->get_default_language()){
  1393. ?>
  1394. <script type="text/javascript">
  1395. addLoadEvent(function(){
  1396. jQuery('.subsubsub li a').each(function(){
  1397. h = jQuery(this).attr('href');
  1398. if(-1 == h.indexOf('?')) urlg = '?'; else urlg = '&';
  1399. jQuery(this).attr('href', h + urlg + 'lang=<?php echo $this->get_current_language()?>');
  1400. });
  1401. jQuery('.column-categories a, .column-tags a, .column-posts a').each(function(){
  1402. jQuery(this).attr('href', jQuery(this).attr('href') + '&lang=<?php echo $this->get_current_language()?>');
  1403. });
  1404. <?php /* needs jQuery 1.3
  1405. jQuery('.column-categories a, .column-tags a, .column-posts a').live('mouseover', function(){
  1406. if(-1 == jQuery(this).attr('href').search('lang='+icl_this_lang)){
  1407. h = jQuery(this).attr('href');
  1408. if(-1 == h.indexOf('?')) urlg = '?'; else urlg = '&';
  1409. jQuery(this).attr('href', h + urlg + 'lang='+icl_this_lang);
  1410. }
  1411. });
  1412. */ ?>
  1413. });
  1414. </script>
  1415. <?php
  1416. }
  1417. if('edit-tags.php' == $pagenow){
  1418. ?>
  1419. <script type="text/javascript">
  1420. addLoadEvent(function(){
  1421. if(jQuery('#edittag [name="_wp_original_http_referer"]').length && jQuery('#edittag [name="_wp_http_referer"]').length){
  1422. jQuery('#edittag [name="_wp_original_http_referer"]').val('<?php echo admin_url('edit-tags.php?taxonomy=' . esc_js($_GET['taxonomy']) . '&lang='.$this->get_current_language().'&message=3') ?>');
  1423. }
  1424. });
  1425. </script>
  1426. <?php
  1427. }
  1428. if('post-new.php' == $pagenow){
  1429. if(isset($_GET['trid'])){
  1430. $translations = $wpdb->get_col($wpdb->prepare("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d", $_GET['trid']));
  1431. remove_filter('option_sticky_posts', array($this,'option_sticky_posts')); // remove filter used to get language relevant stickies. get them all
  1432. $sticky_posts = get_option('sticky_posts');
  1433. add_filter('option_sticky_posts', array($this,'option_sticky_posts')); // add filter back
  1434. $is_sticky = false;
  1435. foreach($translations as $t){
  1436. if(in_array($t, $sticky_posts)){
  1437. $is_sticky = true;
  1438. break;
  1439. }
  1440. }
  1441. if(isset($_GET['trid']) && ($this->settings['sync_ping_status'] || $this->settings['sync_comment_status'])){
  1442. $res = $wpdb->get_row($wpdb->prepare("SELECT comment_status, ping_status FROM {$wpdb->prefix}icl_translations t
  1443. JOIN {$wpdb->posts} p ON t.element_id = p.ID WHERE t.trid=%d", $_GET['trid'])); ?>
  1444. <script type="text/javascript">addLoadEvent(function(){
  1445. <?php if($this->settings['sync_comment_status']): ?>
  1446. <?php if($res->comment_status == 'open'): ?>
  1447. jQuery('#comment_status').attr('checked','checked');
  1448. <?php else: ?>
  1449. jQuery('#comment_status').removeAttr('checked');
  1450. <?php endif; ?>
  1451. <?php endif; ?>
  1452. <?php if($this->settings['sync_ping_status']): ?>
  1453. <?php if($res->ping_status == 'open'): ?>
  1454. jQuery('#ping_status').attr('checked','checked');
  1455. <?php else: ?>
  1456. jQuery('#ping_status').removeAttr('checked');
  1457. <?php endif; ?>
  1458. <?php endif; ?>
  1459. });</script><?php
  1460. }
  1461. if(isset($_GET['trid']) && $this->settings['sync_private_flag']){
  1462. if('private' == $wpdb->get_var($wpdb->prepare("
  1463. SELECT p.post_status FROM {$wpdb->prefix}icl_translations t
  1464. JOIN {$wpdb->posts} p ON t.element_id = p.ID
  1465. WHERE t.trid=%d AND t.element_type='post_post'
  1466. ", $_GET['trid']))){
  1467. ?><script type="text/javascript">addLoadEvent(function(){
  1468. jQuery('#visibility-radio-private').attr('checked','checked');
  1469. jQuery('#post-visibility-display').html('<?php echo icl_js_escape(__('Private', 'sitepress')); ?>');
  1470. });
  1471. </script><?php
  1472. }
  1473. }
  1474. if(isset($_GET['trid']) && $this->settings['sync_post_taxonomies']){
  1475. $post_type = isset($_GET['post_type'])?$_GET['post_type']:'post';
  1476. $source_lang = isset($_GET['source_lang'])?$_GET['source_lang']:$this->get_default_language();
  1477. $translatable_taxs = $this->get_translatable_taxonomies(true, $post_type);
  1478. $all_taxs = get_object_taxonomies($post_type);
  1479. $translations = $this->get_element_translations($_GET['trid'], 'post_' . $post_type);
  1480. $js = array();
  1481. if(!empty($all_taxs)) foreach($all_taxs as $tax){
  1482. $tax_detail = get_taxonomy($tax);
  1483. $terms = get_the_terms($translations[$source_lang]->element_id, $tax);
  1484. $term_names = array();
  1485. if($terms) foreach($terms as $term){
  1486. if($tax_detail->hierarchical){
  1487. if(in_array($tax, $translatable_taxs)){
  1488. $term_id = icl_object_id($term->term_id, $tax, false);
  1489. }else{
  1490. $term_id = $term->term_id;
  1491. }
  1492. $js[] = "jQuery('#in-".$tax."-".$term_id."').attr('checked', 'checked');";
  1493. }else{
  1494. if(in_array($tax, $translatable_taxs)){
  1495. $term_id = icl_object_id($term->term_id, $tax, false);
  1496. if($term_id){
  1497. $term = get_term_by('id', $term_id, $tax);
  1498. $term_names[] = esc_html($term->name);
  1499. }
  1500. }else{
  1501. $term_names[] = esc_html($term->name);
  1502. }
  1503. }
  1504. }
  1505. if($term_names){
  1506. $js[] = "jQuery('#{$tax} .taghint').css('visibility','hidden');";
  1507. $js[] = "jQuery('#new-tag-{$tax}').val('".join(', ', $term_names)."');";
  1508. }
  1509. }
  1510. if($js){
  1511. echo '<script type="text/javascript">';
  1512. echo PHP_EOL . '// <![CDATA[' . PHP_EOL;
  1513. echo 'addLoadEvent(function(){'. PHP_EOL;
  1514. echo join(PHP_EOL, $js);
  1515. echo PHP_EOL . 'jQuery().ready(function() {jQuery(".tagadd").click();jQuery(\'html, body\').prop({scrollTop:0});});'. PHP_EOL;
  1516. echo PHP_EOL . '});'. PHP_EOL;
  1517. echo PHP_EOL . '// ]]>' . PHP_EOL;
  1518. echo '</script>';
  1519. }
  1520. }
  1521. // sync custom fields
  1522. if(!empty($this->settings['translation-management']))
  1523. foreach((array)$this->settings['translation-management']['custom_fields_translation'] as $key=>$sync_opt){
  1524. if($sync_opt == 1){
  1525. $copied_cf[] = $key;
  1526. }
  1527. }
  1528. if(!empty($copied_cf)){
  1529. $source_lang = isset($_GET['source_lang'])?$_GET['source_lang']:$this->get_default_language();
  1530. $lang_details = $this->get_language_details($source_lang);
  1531. $original_custom = get_post_custom($translations[$source_lang]->element_id);
  1532. $copied_cf = array_intersect($copied_cf, array_keys($original_custom));
  1533. $copied_cf = apply_filters('icl_custom_fields_to_be_copied', $copied_cf, $translations[$source_lang]->element_id);
  1534. if(!empty($copied_cf) && (empty($this->user_preferences['notices']) || empty($this->user_preferences['notices']['hide_custom_fields_copy']))){
  1535. $ccf_note = '<img src="' . ICL_PLUGIN_URL . '/res/img/alert.png" alt="Notice" width="16" height="16" style="margin-right:8px" />';
  1536. $ccf_note .= '<a class="icl_user_notice_hide" href="#hide_custom_fields_copy" style="float:right;margin-left:20px;">'.__('Never show this.', 'sitepress') . '</a>';
  1537. $ccf_note .= wp_nonce_field('save_user_preferences_nonce', '_icl_nonce_sup', false, false);
  1538. $ccf_note .= sprintf(__('WPML will copy %s from %s when you save this post.', 'sitepress'), '<i><strong>' . join('</strong>, <strong>', $copied_cf) . '</strong></i>', $lang_details['display_name']);
  1539. $this->admin_notices($ccf_note, 'error');
  1540. }
  1541. }
  1542. }
  1543. ?>
  1544. <?php if(!empty($is_sticky) && $this->settings['sync_sticky_flag']): ?>
  1545. <script type="text/javascript">
  1546. addLoadEvent(
  1547. function(){
  1548. jQuery('#sticky').attr('checked','checked');
  1549. jQuery('#post-visibility-display').html(jQuery('#post-visibility-display').html()+', <?php echo icl_js_escape(__('Sticky', 'sitepress')) ?>');
  1550. });
  1551. </script>
  1552. <?php endif; ?>
  1553. <?php
  1554. }
  1555. if('page-new.php' == $pagenow || ('post-new.php' == $pagenow && isset($_GET['post_type']))){
  1556. if(isset($_GET['trid']) && ($this->settings['sync_page_template'] || $this->settings['sync_page_ordering'])){
  1557. $res = $wpdb->get_row($wpdb->prepare("
  1558. SELECT p.ID, p.menu_order FROM {$wpdb->prefix}icl_translations t
  1559. JOIN {$wpdb->posts} p ON t.element_id = p.ID
  1560. WHERE t.trid=%d AND p.post_type=%s AND t.element_type=%s
  1561. ",$_GET['trid'], $_GET['post_type'], 'post_' . $_GET['post_type']));
  1562. if($this->settings['sync_page_ordering']){
  1563. $menu_order = $res->menu_order;
  1564. }else{
  1565. $menu_order = false;
  1566. }
  1567. if($this->settings['sync_page_template']){
  1568. $page_template = get_post_meta($res->ID, '_wp_page_template', true);
  1569. }else{
  1570. $page_template = false;
  1571. }
  1572. if($menu_order || $page_template){
  1573. ?><script type="text/javascript">addLoadEvent(function(){ <?php
  1574. if($menu_order){ ?>
  1575. jQuery('#menu_order').val(<?php echo $menu_order ?>);
  1576. <?php }
  1577. if($page_template && 'default' != $page_template){ ?>
  1578. jQuery('#page_template').val('<?php echo $page_template ?>');
  1579. <?php }
  1580. ?>});</script><?php
  1581. }
  1582. }
  1583. }elseif('edit-comments.php' == $pagenow || 'index.php' == $pagenow || 'post.php' == $pagenow){
  1584. wp_enqueue_script('sitepress-' . $page_basename, ICL_PLUGIN_URL . '/res/js/comments-translation.js', array(), ICL_SITEPRESS_VERSION);
  1585. }
  1586. // sync post dates
  1587. if(icl_is_post_edit()){
  1588. if($this->settings['sync_post_date']){
  1589. $post_type = isset($_GET['post_type'])?$_GET['post_type']:'post';
  1590. if(isset($_GET['trid'])){
  1591. $trid = intval($_GET['trid']);
  1592. }else{
  1593. $post_id = @intval($_GET['post']);
  1594. $trid = $this->get_element_trid($post_id, 'post_' . $post_type);
  1595. }
  1596. $translations = $this->get_element_translations($trid, 'post_' . $post_type);
  1597. if(!empty($translations) && isset($translations[$this->get_current_language()]) && !$translations[$this->get_current_language()]->original){
  1598. $source_lang = isset($_GET['source_lang'])?$_GET['source_lang']:$this->get_default_language();
  1599. $original_date = $wpdb->get_var($wpdb->prepare("SELECT post_date FROM {$wpdb->posts} WHERE ID=%d", $translations[$source_lang]->element_id));
  1600. $exp = explode(' ', $original_date);
  1601. list($aa, $mm, $jj) = explode('-', $exp[0]);
  1602. list($hh, $mn, $ss) = explode(':', $exp[1]);
  1603. ?>
  1604. <script type="text/javascript">
  1605. addLoadEvent(
  1606. function(){
  1607. jQuery('#aa').val('<?php echo $aa ?>').attr('readonly','readonly');
  1608. jQuery('#mm').val('<?php echo $mm ?>').attr('readonly','readonly');
  1609. jQuery('#jj').val('<?php echo $jj ?>').attr('readonly','readonly');
  1610. jQuery('#hh').val('<?php echo $hh ?>').attr('readonly','readonly');
  1611. jQuery('#mn').val('<?php echo $mn ?>').attr('readonly','readonly');
  1612. jQuery('#ss').val('<?php echo $ss ?>').attr('readonly','readonly');
  1613. jQuery('#timestamp b').html('<?php esc_html_e('copy from original', 'sitepress') ?>');
  1614. jQuery('#timestamp').next().html('<?php esc_html_e('show', 'sitepress') ?>');
  1615. });
  1616. </script>
  1617. <?php
  1618. }
  1619. }
  1620. }
  1621. if('page-new.php' == $pagenow && isset($_GET['trid']) && $this->settings['sync_post_format'] && function_exists('get_post_format')){
  1622. $format = get_post_format($wpdb->get_var($wpdb->prepare(
  1623. "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d and language_code=%s", $_GET['trid'], $_GET['source_lang'])));
  1624. ?><script type="text/javascript">addLoadEvent(function(){
  1625. jQuery('#post-format-<?php echo $format ?>').attr('checked','checked');
  1626. });
  1627. </script><?php
  1628. }
  1629. if (is_admin()) {
  1630. wp_enqueue_script( 'thickbox' );
  1631. wp_enqueue_script( 'theme-preview' );
  1632. wp_enqueue_script( 'sitepress-icl_reminders', ICL_PLUGIN_URL . '/res/js/icl_reminders.js', array(), ICL_SITEPRESS_VERSION);
  1633. }
  1634. //if('content-translation' == $page_basename) {
  1635. // wp_enqueue_script('icl-sidebar-scripts', ICL_PLUGIN_URL . '/res/js/icl_sidebar.js', array(), ICL_SITEPRESS_VERSION);
  1636. //}
  1637. if('languages' == $page_basename || 'string-translation' == $page_basename) {
  1638. wp_enqueue_script( 'colorpicker' );
  1639. }
  1640. }
  1641. function js_load(){
  1642. if(is_admin() && !defined('DOING_AJAX')){
  1643. if(isset($_GET['page'])){
  1644. $page = basename($_GET['page']);
  1645. $page_basename = str_replace('.php','',$page);
  1646. }else{
  1647. $page_basename = false;
  1648. }
  1649. wp_enqueue_script('sitepress-scripts', ICL_PLUGIN_URL . '/res/js/scripts.js', array('jquery'), ICL_SITEPRESS_VERSION);
  1650. if(isset($page_basename) && file_exists(ICL_PLUGIN_PATH . '/res/js/'.$page_basename.'.js')){
  1651. wp_enqueue_script('sitepress-' . $page_basename, ICL_PLUGIN_URL . '/res/js/'.$page_basename.'.js', array(), ICL_SITEPRESS_VERSION);
  1652. }
  1653. }
  1654. }
  1655. function front_end_js(){
  1656. if(defined('ICL_DONT_LOAD_LANGUAGES_JS') && ICL_DONT_LOAD_LANGUAGES_JS){
  1657. return;
  1658. }
  1659. echo '<script type="text/javascript">var icl_lang = \''.$this->this_lang.'\';var icl_home = \''.$this->language_url().'\';</script>' . PHP_EOL;
  1660. echo '<script type="text/javascript" src="'. ICL_PLUGIN_URL . '/res/js/sitepress.js"></script>' . PHP_EOL;
  1661. }
  1662. function js_scripts_categories(){
  1663. wp_enqueue_script('sitepress-categories', ICL_PLUGIN_URL . '/res/js/categories.js', array(), ICL_SITEPRESS_VERSION);
  1664. }
  1665. function js_scripts_tags(){
  1666. wp_enqueue_script('sitepress-tags', ICL_PLUGIN_URL . '/res/js/tags.js', array(), ICL_SITEPRESS_VERSION);
  1667. }
  1668. function rtl_fix(){
  1669. global $wp_styles;
  1670. if($this->is_rtl()){
  1671. $wp_styles->text_direction = 'rtl';
  1672. }
  1673. }
  1674. function css_setup(){
  1675. if(isset($_GET['page'])){
  1676. $page = basename($_GET['page']);
  1677. $page_basename = str_replace('.php','',$page);
  1678. }
  1679. wp_enqueue_style('sitepress-style', ICL_PLUGIN_URL . '/res/css/style.css', array(), ICL_SITEPRESS_VERSION);
  1680. if(isset($page_basename) && file_exists(ICL_PLUGIN_PATH . '/res/css/'.$page_basename.'.css')){
  1681. wp_enqueue_style('sitepress-' . $page_basename, ICL_PLUGIN_URL . '/res/css/'.$page_basename.'.css', array(), ICL_SITEPRESS_VERSION);
  1682. }
  1683. if (is_admin()) {
  1684. wp_enqueue_style('thickbox');
  1685. }
  1686. }
  1687. function transfer_icl_account($create_account_and_transfer) {
  1688. $user = $_POST['user'];
  1689. $user['site_id'] = $this->settings['site_id'];
  1690. $user['accesskey'] = $this->settings['access_key'];
  1691. $user['create_account'] = $create_account_and_transfer ? '1' : '0';
  1692. $icl_query = new ICanLocalizeQuery();
  1693. list($success, $access_key) = $icl_query->transfer_account($user);
  1694. if ($success) {
  1695. $this->settings['access_key'] = $access_key;
  1696. // set the support data the same.
  1697. $this->settings['support_access_key'] = $access_key;
  1698. $this->save_settings();
  1699. return true;
  1700. } else {
  1701. $_POST['icl_form_errors'] = $access_key;
  1702. return false;
  1703. }
  1704. }
  1705. function process_forms(){
  1706. global $wpdb;
  1707. require_once ICL_PLUGIN_PATH . '/lib/Snoopy.class.php';
  1708. require_once ICL_PLUGIN_PATH . '/lib/xml2array.php';
  1709. require_once ICL_PLUGIN_PATH . '/lib/icl_api.php';
  1710. if(isset($_POST['icl_post_action'])){
  1711. switch($_POST['icl_post_action']){
  1712. case 'save_theme_localization':
  1713. $locales = array();
  1714. foreach($_POST as $k=>$v){
  1715. if(0 !== strpos($k, 'locale_file_name_') || !trim($v)) continue;
  1716. $locales[str_replace('locale_file_name_','',$k)] = $v;
  1717. }
  1718. if(!empty($locales)){
  1719. $this->set_locale_file_names($locales);
  1720. }
  1721. break;
  1722. }
  1723. return;
  1724. }
  1725. $create_account = isset($_POST['icl_create_account_nonce']) && $_POST['icl_create_account_nonce']==wp_create_nonce('icl_create_account');
  1726. $create_account_and_transfer = isset($_POST['icl_create_account_and_transfer_nonce']) && $_POST['icl_create_account_and_transfer_nonce']==wp_create_nonce('icl_create_account_and_transfer');
  1727. $config_account = isset($_POST['icl_configure_account_nonce']) && $_POST['icl_configure_account_nonce']==wp_create_nonce('icl_configure_account');
  1728. $create_support_account = isset($_POST['icl_create_support_account_nonce']) && $_POST['icl_create_support_account_nonce']==wp_create_nonce('icl_create_support_account');
  1729. $config_support_account = isset($_POST['icl_configure_support_account_nonce']) && $_POST['icl_configure_support_account_nonce']==wp_create_nonce('icl_configure_support_account');
  1730. $use_existing_account = isset($_POST['icl_use_account_nonce']) && $_POST['icl_use_account_nonce']==wp_create_nonce('icl_use_account');
  1731. $transfer_to_account = isset($_POST['icl_transfer_account_nonce']) && $_POST['icl_transfer_account_nonce']==wp_create_nonce('icl_transfer_account');
  1732. if( $create_account || $config_account || $create_support_account || $config_support_account){
  1733. if (isset($_POST['icl_content_trans_setup_back_2'])) {
  1734. // back button in wizard mode.
  1735. $this->settings['content_translation_setup_wizard_step'] = 2;
  1736. $this->save_settings();
  1737. } else {
  1738. $user = $_POST['user'];
  1739. $user['create_account'] = (isset($_POST['icl_create_account_nonce']) ||
  1740. isset($_POST['icl_create_support_account_nonce'])) ? 1 : 0;
  1741. $user['platform_kind'] = 2;
  1742. $user['cms_kind'] = 1;
  1743. $user['blogid'] = $wpdb->blogid?$wpdb->blogid:1;
  1744. $user['url'] = get_option('home');
  1745. $user['title'] = get_option('blogname');
  1746. $user['description'] = $this->settings['icl_site_description'];
  1747. $user['is_verified'] = 1;
  1748. if($user['create_account'] && defined('ICL_AFFILIATE_ID') && defined('ICL_AFFILIATE_KEY')){
  1749. $user['affiliate_id'] = ICL_AFFILIATE_ID;
  1750. $user['affiliate_key'] = ICL_AFFILIATE_KEY;
  1751. }
  1752. $user['interview_translators'] = $this->settings['interview_translators'];
  1753. $user['project_kind'] = $this->settings['website_kind'];
  1754. /*
  1755. if(is_null($user['project_kind']) || $user['project_kind']==''){
  1756. $_POST['icl_form_errors'] = __('Please select the kind of website','sitepress');
  1757. return;
  1758. }
  1759. */
  1760. $user['pickup_type'] = intval($this->settings['translation_pickup_method']);
  1761. $notifications = 0;
  1762. if ( $this->settings['icl_notify_complete']){
  1763. $notifications += 1;
  1764. }
  1765. if ( $this->settings['alert_delay']){
  1766. $notifications += 2;
  1767. }
  1768. $user['notifications'] = $notifications;
  1769. // prepare language pairs
  1770. $pay_per_use = $this->settings['translator_choice'] == 1;
  1771. $language_pairs = $this->settings['language_pairs'];
  1772. $lang_pairs = array();
  1773. if(isset($language_pairs)){
  1774. foreach($language_pairs as $k=>$v){
  1775. $english_fr = $wpdb->get_var("SELECT english_name FROM {$wpdb->prefix}icl_languages WHERE code='{$k}' ");
  1776. foreach($v as $k=>$v){
  1777. $incr++;
  1778. $english_to = $wpdb->get_var("SELECT english_name FROM {$wpdb->prefix}icl_languages WHERE code='{$k}' ");
  1779. $lang_pairs['from_language'.$incr] = ICL_Pro_Translation::server_languages_map($english_fr);
  1780. $lang_pairs['to_language'.$incr] = ICL_Pro_Translation::server_languages_map($english_to);
  1781. if ($pay_per_use) {
  1782. $lang_pairs['pay_per_use'.$incr] = 1;
  1783. }
  1784. }
  1785. }
  1786. }
  1787. $icl_query = new ICanLocalizeQuery();
  1788. list($site_id, $access_key) = $icl_query->createAccount(array_merge($user,$lang_pairs));
  1789. if(!$site_id){
  1790. $user['pickup_type'] = ICL_PRO_TRANSLATION_PICKUP_POLLING;
  1791. list($site_id, $access_key) = $icl_query->createAccount(array_merge($user,$lang_pairs));
  1792. }
  1793. if(!$site_id){
  1794. if ($access_key) {
  1795. $_POST['icl_form_errors'] = $access_key;
  1796. } else {
  1797. $_POST['icl_form_errors'] = __('An unknown error has occurred when communicating with the ICanLocalize server. Please try again.', 'sitepress');
  1798. // We will force the next try to be http.
  1799. update_option('_force_mp_post_http', 1);
  1800. }
  1801. }else{
  1802. if ($create_account || $config_account) {
  1803. $iclsettings['site_id'] = $site_id;
  1804. $iclsettings['access_key'] = $access_key;
  1805. $iclsettings['icl_account_email'] = $user['email'];
  1806. // set the support data the same.
  1807. $iclsettings['support_site_id'] = $site_id;
  1808. $iclsettings['support_access_key'] = $access_key;
  1809. $iclsettings['support_icl_account_email'] = $user['email'];
  1810. } else {
  1811. $iclsettings['support_site_id'] = $site_id;
  1812. $iclsettings['support_access_key'] = $access_key;
  1813. $iclsettings['support_icl_account_email'] = $user['email'];
  1814. }
  1815. if(isset($user['pickup_type']) && $user['pickup_type']==ICL_PRO_TRANSLATION_PICKUP_POLLING){
  1816. $iclsettings['translation_pickup_method'] = ICL_PRO_TRANSLATION_PICKUP_POLLING;
  1817. }
  1818. $this->save_settings($iclsettings);
  1819. if($user['create_account']==1){
  1820. $_POST['icl_form_success'] = __('A project on ICanLocalize has been created.', 'sitepress') . '<br />';
  1821. }else{
  1822. $_POST['icl_form_success'] = __('Project added','sitepress');
  1823. }
  1824. $this->get_icl_translator_status($iclsettings);
  1825. $this->save_settings($iclsettings);
  1826. }
  1827. if (!$create_support_account &&
  1828. !$config_support_account &&
  1829. intval($site_id) > 0 &&
  1830. $access_key &&
  1831. $this->settings['content_translation_setup_complete'] == 0 &&
  1832. $this->settings['content_translation_setup_wizard_step'] == 3 &&
  1833. !isset($_POST['icl_form_errors'])) {
  1834. // we are running the wizard, so we can finish it now.
  1835. $this->settings['content_translation_setup_complete'] = 1;
  1836. $this->settings['content_translation_setup_wizard_step'] = 0;
  1837. $this->save_settings();
  1838. }
  1839. }
  1840. }
  1841. elseif ($use_existing_account || $transfer_to_account || $create_account_and_transfer) {
  1842. if (isset($_POST['icl_content_trans_setup_back_2'])) {
  1843. // back button in wizard mode.
  1844. $this->settings['content_translation_setup_wizard_step'] = 2;
  1845. $this->save_settings();
  1846. } else {
  1847. if ($transfer_to_account) {
  1848. $_POST['user']['email'] = $_POST['user']['email2'];
  1849. }
  1850. // we will be using the support account for the icl_account
  1851. $this->settings['site_id'] = $this->settings['support_site_id'];
  1852. $this->settings['access_key'] = $this->settings['support_access_key'];
  1853. $this->settings['icl_account_email'] = $this->settings['support_icl_account_email'];
  1854. $this->save_settings();
  1855. update_icl_account();
  1856. if ($transfer_to_account || $create_account_and_transfer) {
  1857. if (!$this->transfer_icl_account($create_account_and_transfer)) {
  1858. return;
  1859. }
  1860. }
  1861. // we are running the wizard, so we can finish it now.
  1862. $this->settings['content_translation_setup_complete'] = 1;
  1863. $this->settings['content_translation_setup_wizard_step'] = 0;
  1864. $this->save_settings();
  1865. $iclsettings['site_id'] = $this->settings['site_id'];
  1866. $iclsettings['access_key'] = $this->settings['access_key'];
  1867. $this->get_icl_translator_status($iclsettings);
  1868. $this->save_settings($iclsettings);
  1869. }
  1870. }
  1871. elseif(isset($_POST['icl_initial_languagenonce']) && $_POST['icl_initial_languagenonce']==wp_create_nonce('icl_initial_language')){
  1872. $this->prepopulate_translations($_POST['icl_initial_language_code']);
  1873. $wpdb->update($wpdb->prefix . 'icl_languages', array('active'=>'1'), array('code'=>$_POST['icl_initial_language_code']));
  1874. $blog_default_cat = get_option('default_category');
  1875. $blog_default_cat_tax_id = $wpdb->get_var("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id='{$blog_default_cat}' AND taxonomy='category'");
  1876. if(isset($_POST['save_one_language'])){
  1877. $this->settings['setup_wizard_step'] = 0;
  1878. $this->settings['setup_complete'] = 1;
  1879. }else{
  1880. $this->settings['setup_wizard_step'] = 2;
  1881. }
  1882. $this->settings['default_categories'] = array($_POST['icl_initial_language_code'] => $blog_default_cat_tax_id);
  1883. $this->settings['existing_content_language_verified'] = 1;
  1884. $this->settings['default_language'] = $_POST['icl_initial_language_code'];
  1885. $this->settings['admin_default_language'] = $this->admin_language = $_POST['icl_initial_language_code'];
  1886. // set the locale in the icl_locale_map (if it's not set)
  1887. if(!$wpdb->get_var("SELECT code FROM {$wpdb->prefix}icl_locale_map WHERE code='{$_POST['icl_initial_language_code']}'")){
  1888. $default_locale = $wpdb->get_var("SELECT default_locale FROM {$wpdb->prefix}icl_languages WHERE code='{$_POST['icl_initial_language_code']}'");
  1889. if($default_locale){
  1890. $wpdb->insert($wpdb->prefix.'icl_locale_map', array('code'=>$_POST['icl_initial_language_code'], 'locale'=>$default_locale));
  1891. }
  1892. }
  1893. $this->save_settings();
  1894. global $sitepress_settings;
  1895. $sitepress_settings = $this->settings;
  1896. $this->get_active_languages(true); //refresh active languages list
  1897. do_action('icl_initial_language_set');
  1898. }elseif(isset($_POST['icl_language_pairs_formnounce']) && $_POST['icl_language_pairs_formnounce'] == wp_create_nonce('icl_language_pairs_form')) {
  1899. $this->save_language_pairs();
  1900. $this->settings['content_translation_languages_setup'] = 1;
  1901. // Move onto the site description page
  1902. $this->settings['content_translation_setup_wizard_step'] = 2;
  1903. $this->settings['website_kind'] = 2;
  1904. $this->settings['interview_translators'] = 1;
  1905. $this->save_settings();
  1906. }elseif(isset($_POST['icl_site_description_wizardnounce']) && $_POST['icl_site_description_wizardnounce'] == wp_create_nonce('icl_site_description_wizard')) {
  1907. if(isset($_POST['icl_content_trans_setup_back_2'])){
  1908. // back button.
  1909. $this->settings['content_translation_languages_setup'] = 0;
  1910. $this->settings['content_translation_setup_wizard_step'] = 1;
  1911. $this->save_settings();
  1912. }elseif(isset($_POST['icl_content_trans_setup_next_2']) || isset($_POST['icl_content_trans_setup_next_2_enter'])){
  1913. // next button.
  1914. $description = $_POST['icl_description'];
  1915. if ($description == "") {
  1916. $_POST['icl_form_errors'] = __('Please provide a short description of the website so that translators know what background is required from them.','sitepress');
  1917. } else {
  1918. $this->settings['icl_site_description'] = $description;
  1919. $this->settings['content_translation_setup_wizard_step'] = 3;
  1920. $this->save_settings();
  1921. }
  1922. }
  1923. }
  1924. }
  1925. function prepopulate_translations($lang){
  1926. global $wpdb;
  1927. if($this->settings['existing_content_language_verified']) return;
  1928. $this->icl_translations_cache->clear();
  1929. // case of icl_sitepress_settings accidentally lost
  1930. // if there's at least one translation do not initialize the languages for elements
  1931. $one_translation = $wpdb->get_var($wpdb->prepare("SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE language_code<>%s", $lang));
  1932. if($one_translation){
  1933. return;
  1934. }
  1935. mysql_query("TRUNCATE TABLE {$wpdb->prefix}icl_translations");
  1936. mysql_query("
  1937. INSERT INTO {$wpdb->prefix}icl_translations(element_type, element_id, trid, language_code, source_language_code)
  1938. SELECT CONCAT('post_',post_type), ID, ID, '{$lang}', NULL FROM {$wpdb->posts} WHERE post_status IN ('draft', 'publish','schedule','future','private', 'pending')
  1939. ");
  1940. $maxtrid = 1 + $wpdb->get_var("SELECT MAX(trid) FROM {$wpdb->prefix}icl_translations");
  1941. global $wp_taxonomies;
  1942. $taxonomies = array_keys((array)$wp_taxonomies);
  1943. foreach($taxonomies as $tax){
  1944. mysql_query("
  1945. INSERT INTO {$wpdb->prefix}icl_translations(element_type, element_id, trid, language_code, source_language_code)
  1946. SELECT 'tax_".$tax."', term_taxonomy_id, {$maxtrid}+term_taxonomy_id, '{$lang}', NULL FROM {$wpdb->term_taxonomy} WHERE taxonomy = '{$tax}'
  1947. ");
  1948. $maxtrid = 1 + $wpdb->get_var("SELECT MAX(trid) FROM {$wpdb->prefix}icl_translations");
  1949. }
  1950. mysql_query("
  1951. INSERT INTO {$wpdb->prefix}icl_translations(element_type, element_id, trid, language_code, source_language_code)
  1952. SELECT 'comment', comment_ID, {$maxtrid}+comment_ID, '{$lang}', NULL FROM {$wpdb->comments}
  1953. ");
  1954. }
  1955. function post_edit_language_options(){
  1956. global $wpdb, $post, $iclTranslationManagement;
  1957. if(!function_exists('post_type_supports') || post_type_supports($post->post_type, 'editor')){
  1958. add_action('icl_post_languages_options_after', array($this, 'copy_from_original'));
  1959. }
  1960. if (current_user_can('manage_options')) {
  1961. add_meta_box('icl_div_config', __('Multilingual Content Setup', 'sitepress'),
  1962. array($this, 'meta_box_config'), $post->post_type, 'normal', 'low');
  1963. }
  1964. if(isset($_POST['icl_action']) && $_POST['icl_action'] == 'icl_mcs_inline'){
  1965. if(!in_array($_POST['custom_post'], array('post', 'page'))){
  1966. $iclsettings['custom_posts_sync_option'][$_POST['custom_post']] = @intval($_POST['translate']);
  1967. if(@intval($_POST['translate'])){
  1968. $this->verify_post_translations($_POST['custom_post']);
  1969. }
  1970. }
  1971. if(!empty($_POST['custom_taxs_off'])){
  1972. foreach($_POST['custom_taxs_off'] as $off){
  1973. $iclsettings['taxonomies_sync_option'][$off] = 0;
  1974. }
  1975. }
  1976. if(!empty($_POST['custom_taxs_on'])){
  1977. foreach($_POST['custom_taxs_on'] as $on){
  1978. $iclsettings['taxonomies_sync_option'][$on] = 1;
  1979. $this->verify_taxonomy_translations($on);
  1980. }
  1981. }
  1982. if(!empty($_POST['cfnames'])){
  1983. foreach($_POST['cfnames'] as $k=>$v){
  1984. $custom_field_name = base64_decode($v);
  1985. $iclTranslationManagement->settings['custom_fields_translation'][$custom_field_name] = @intval($_POST['cfvals'][$k]);
  1986. $iclTranslationManagement->save_settings();
  1987. // sync the custom fields for the current post
  1988. if(1 == @intval($_POST['cfvals'][$k])){
  1989. $trid = $this->get_element_trid($_POST['post_id'], 'post_' . $_POST['custom_post']);
  1990. $translations = $this->get_element_translations($trid, 'post_' . $_POST['custom_post']);
  1991. // determine original post id
  1992. foreach($translations as $t){
  1993. if($t->original){ $original_post_id = $t->element_id; break;}
  1994. }
  1995. // get a list of $custom_field_name values that the original document has
  1996. $custom_fields_copy = get_post_meta($original_post_id, $custom_field_name);
  1997. foreach($translations as $t){
  1998. if($t->original) continue;
  1999. // if none, then attempt to delete any that the tranlations would have
  2000. if(empty($custom_fields_copy)){
  2001. delete_post_meta($t->element_id, $custom_field_name);
  2002. }else{
  2003. // get a list of $custom_field_name values that the translated document has
  2004. $translation_cfs = get_post_meta($t->element_id, $custom_field_name);
  2005. // see what elements have been deleted in the original document
  2006. $deleted_fields = $translation_cfs;
  2007. foreach($custom_fields_copy as $cfc){
  2008. $tc_key = array_search($cfc, $translation_cfs);
  2009. if($tc_key !== false){
  2010. unset($deleted_fields[$tc_key]);
  2011. }
  2012. }
  2013. if(!empty($deleted_fields)){
  2014. foreach($deleted_fields as $meta_value){
  2015. delete_post_meta($t->element_id, $custom_field_name, $meta_value);
  2016. }
  2017. }
  2018. // update each custom field in the translated document
  2019. foreach($custom_fields_copy as $meta_value){
  2020. if(!in_array($meta_value, $translation_cfs)){
  2021. // if it doesn't exist, add
  2022. add_post_meta($t->element_id, $custom_field_name, $meta_value);
  2023. }else{
  2024. // do nothin'
  2025. }
  2026. }
  2027. }
  2028. }
  2029. }
  2030. }
  2031. }
  2032. if(!empty($iclsettings)){
  2033. $this->save_settings($iclsettings);
  2034. }
  2035. }
  2036. $post_types = array_keys($this->get_translatable_documents());
  2037. if(in_array($post->post_type, $post_types)){
  2038. add_meta_box('icl_div', __('Language', 'sitepress'), array($this,'meta_box'), $post->post_type, 'side', 'high');
  2039. }
  2040. }
  2041. function set_element_language_details($el_id, $el_type='post_post', $trid, $language_code, $src_language_code = null, $check_duplicates = true){
  2042. global $wpdb;
  2043. // special case for posts and taxonomies
  2044. // check if a different record exists for the same ID
  2045. // if it exists don't save the new element and get out
  2046. if($check_duplicates && $el_id){
  2047. $exp = explode('_', $el_type);
  2048. $_type = $exp[0];
  2049. if(in_array($_type, array('post', 'tax'))){
  2050. $_el_exists = $wpdb->get_var("
  2051. SELECT translation_id FROM {$wpdb->prefix}icl_translations
  2052. WHERE element_id={$el_id} AND element_type <> '{$el_type}' AND element_type LIKE '{$_type}\\_%'");
  2053. if($_el_exists){
  2054. trigger_error('Element ID already exists with a different type', E_USER_NOTICE);
  2055. return false;
  2056. }
  2057. }
  2058. }
  2059. if($trid){ // it's a translation of an existing element
  2060. // check whether we have an orphan translation - the same trid and language but a different element id
  2061. $translation_id = $wpdb->get_var("
  2062. SELECT translation_id FROM {$wpdb->prefix}icl_translations
  2063. WHERE trid = '{$trid}'
  2064. AND language_code = '{$language_code}'
  2065. AND element_id <> '{$el_id}'
  2066. ");
  2067. if($translation_id){
  2068. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_translations WHERE translation_id={$translation_id}");
  2069. $this->icl_translations_cache->clear();
  2070. }
  2071. if(!is_null($el_id) && $translation_id = $wpdb->get_var("SELECT translation_id FROM {$wpdb->prefix}icl_translations
  2072. WHERE element_type='{$el_type}' AND element_id='{$el_id}' AND trid='{$trid}' AND element_id IS NOT NULL")){
  2073. //case of language change
  2074. $wpdb->update($wpdb->prefix.'icl_translations',
  2075. array('language_code'=>$language_code),
  2076. array('translation_id'=>$translation_id));
  2077. } elseif(!is_null($el_id) && $translation_id = $wpdb->get_var("SELECT translation_id FROM {$wpdb->prefix}icl_translations
  2078. WHERE element_type='{$el_type}' AND element_id='{$el_id}' AND element_id IS NOT NULL ")){
  2079. //case of changing the "translation of"
  2080. if(empty($src_language_code))
  2081. $src_language_code = $wpdb->get_var("SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE trid={$trid} AND source_language_code IS NULL");
  2082. $wpdb->update($wpdb->prefix.'icl_translations',
  2083. array('trid'=>$trid, 'language_code'=>$language_code, 'source_language_code'=>$src_language_code),
  2084. array('element_type'=>$el_type, 'element_id'=>$el_id));
  2085. $this->icl_translations_cache->clear();
  2086. } elseif($translation_id = $wpdb->get_var($wpdb->prepare("
  2087. SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND language_code='%s' AND element_id IS NULL",
  2088. $trid, $language_code ))){
  2089. $wpdb->update($wpdb->prefix.'icl_translations',
  2090. array('element_id'=>$el_id),
  2091. array('translation_id'=>$translation_id)
  2092. );
  2093. }else{
  2094. //get source
  2095. $src_language_code = $wpdb->get_var("SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE trid={$trid} AND source_language_code IS NULL");
  2096. // case of adding a new language
  2097. $new = array(
  2098. 'trid'=>$trid,
  2099. 'element_type'=>$el_type,
  2100. 'language_code'=>$language_code,
  2101. 'source_language_code'=>$src_language_code
  2102. );
  2103. if($el_id){
  2104. $new['element_id'] = $el_id;
  2105. }
  2106. $wpdb->insert($wpdb->prefix.'icl_translations', $new);
  2107. $translation_id = $wpdb->insert_id;
  2108. $this->icl_translations_cache->clear();
  2109. }
  2110. }else{ // it's a new element or we are removing it from a trid
  2111. if($translation_id = $wpdb->get_var("
  2112. SELECT translation_id
  2113. FROM {$wpdb->prefix}icl_translations WHERE element_type='{$el_type}' AND element_id='{$el_id}' AND element_id IS NOT NULL"
  2114. )){
  2115. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_translations WHERE translation_id={$translation_id}");
  2116. $this->icl_translations_cache->clear();
  2117. }
  2118. $trid = 1 + $wpdb->get_var("SELECT MAX(trid) FROM {$wpdb->prefix}icl_translations");
  2119. $new = array(
  2120. 'trid'=>$trid,
  2121. 'element_type'=>$el_type,
  2122. 'language_code'=>$language_code
  2123. );
  2124. if($el_id){
  2125. $new['element_id'] = $el_id;
  2126. }
  2127. $wpdb->insert($wpdb->prefix.'icl_translations', $new);
  2128. $translation_id = $wpdb->insert_id;
  2129. }
  2130. return $translation_id;
  2131. }
  2132. function delete_element_translation($trid, $el_type, $language_code = false){
  2133. global $wpdb;
  2134. $trid = intval($trid);
  2135. $el_type = $wpdb->escape($el_type);
  2136. $where = '';
  2137. if($language_code){
  2138. $where .= " AND language_code='".$wpdb->escape($language_code)."'";
  2139. }
  2140. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_translations WHERE trid='{$trid}' AND element_type='{$el_type}' {$where}");
  2141. $this->icl_translations_cache->clear();
  2142. }
  2143. function get_element_language_details($el_id, $el_type='post_post'){
  2144. global $wpdb;
  2145. static $pre_load_done = false;
  2146. if (!$pre_load_done && !ICL_DISABLE_CACHE) {
  2147. // search previous queries for a group of posts
  2148. foreach ($this->queries as $query){
  2149. $pos = strstr($query, 'post_id IN (');
  2150. if ($pos !== FALSE) {
  2151. $group = substr($pos, 10);
  2152. $group = substr($group, 0, strpos($group, ')') + 1);
  2153. $query =
  2154. "SELECT element_id, trid, language_code, source_language_code
  2155. FROM {$wpdb->prefix}icl_translations
  2156. WHERE element_id IN {$group} AND element_type='{$el_type}'";
  2157. $ret = $wpdb->get_results($query);
  2158. foreach($ret as $details){
  2159. if (isset($this->icl_translations_cache)) {
  2160. $this->icl_translations_cache->set($details->element_id.$el_type, $details);
  2161. }
  2162. }
  2163. // get the taxonomy for the posts for later use
  2164. // categories first
  2165. $query =
  2166. "SELECT DISTINCT(tr.term_taxonomy_id), tt.term_id, tt.taxonomy, icl.trid, icl.language_code, icl.source_language_code
  2167. FROM {$wpdb->prefix}term_relationships as tr
  2168. LEFT JOIN {$wpdb->prefix}term_taxonomy AS tt
  2169. ON tr.term_taxonomy_id = tt.term_taxonomy_id
  2170. LEFT JOIN {$wpdb->prefix}icl_translations as icl ON tr.term_taxonomy_id = icl.element_id
  2171. WHERE tr.object_id IN {$group}
  2172. AND (icl.element_type='tax_category' and tt.taxonomy='category')
  2173. ";
  2174. $query .= "UNION
  2175. ";
  2176. $query .=
  2177. "SELECT DISTINCT(tr.term_taxonomy_id), tt.term_id, tt.taxonomy, icl.trid, icl.language_code, icl.source_language_code
  2178. FROM {$wpdb->prefix}term_relationships as tr
  2179. LEFT JOIN {$wpdb->prefix}term_taxonomy AS tt
  2180. ON tr.term_taxonomy_id = tt.term_taxonomy_id
  2181. LEFT JOIN {$wpdb->prefix}icl_translations as icl ON tr.term_taxonomy_id = icl.element_id
  2182. WHERE tr.object_id IN {$group}
  2183. AND (icl.element_type='tax_post_tag' and tt.taxonomy='post_tag')"
  2184. ;
  2185. global $wp_taxonomies;
  2186. $custom_taxonomies = array_diff(array_keys($wp_taxonomies), array('post_tag','category','link_category'));
  2187. if(!empty($custom_taxonomies)){
  2188. foreach($custom_taxonomies as $tax){
  2189. $query .= " UNION
  2190. SELECT DISTINCT(tr.term_taxonomy_id), tt.term_id, tt.taxonomy, icl.trid, icl.language_code, icl.source_language_code
  2191. FROM {$wpdb->prefix}term_relationships as tr
  2192. LEFT JOIN {$wpdb->prefix}term_taxonomy AS tt
  2193. ON tr.term_taxonomy_id = tt.term_taxonomy_id
  2194. LEFT JOIN {$wpdb->prefix}icl_translations as icl ON tr.term_taxonomy_id = icl.element_id
  2195. WHERE tr.object_id IN {$group}
  2196. AND (icl.element_type='tax_{$tax}' and tt.taxonomy='{$tax}')"
  2197. ;
  2198. }
  2199. }
  2200. $ret = $wpdb->get_results($query);
  2201. foreach($ret as $details){
  2202. // save language details
  2203. $lang_details = new stdClass();
  2204. $lang_details->trid = $details->trid;
  2205. $lang_details->language_code = $details->language_code;
  2206. $lang_details->source_language_code = $details->source_language_code;
  2207. if (isset($this->icl_translations_cache)) {
  2208. $this->icl_translations_cache->set($details->term_taxonomy_id.'tax_' . $details->taxonomy, $lang_details);
  2209. // save the term taxonomy
  2210. $this->icl_term_taxonomy_cache->set('category_'.$details->term_id, $details->term_taxonomy_id);
  2211. }
  2212. }
  2213. break;
  2214. }
  2215. }
  2216. $pre_load_done = true;
  2217. }
  2218. if (isset($this->icl_translations_cache) && $this->icl_translations_cache->has_key($el_id.$el_type)) {
  2219. return $this->icl_translations_cache->get($el_id.$el_type);
  2220. }
  2221. $details = $wpdb->get_row("
  2222. SELECT trid, language_code, source_language_code
  2223. FROM {$wpdb->prefix}icl_translations
  2224. WHERE element_id='{$el_id}' AND element_type='{$el_type}'");
  2225. if (isset($this->icl_translations_cache)) {
  2226. $this->icl_translations_cache->set($el_id.$el_type, $details);
  2227. }
  2228. return $details;
  2229. }
  2230. function save_post_actions($pidd, $post){
  2231. global $wpdb;
  2232. list($post_type, $post_status) = $wpdb->get_row("SELECT post_type, post_status FROM {$wpdb->posts} WHERE ID = " . $pidd, ARRAY_N);
  2233. // exceptions
  2234. if(
  2235. !$this->is_translated_post_type($post_type)
  2236. || isset($_POST['autosave'])
  2237. || isset($_POST['skip_sitepress_actions'])
  2238. || (isset($_POST['post_ID']) && $_POST['post_ID']!=$pidd) || (isset($_POST['post_type']) && $_POST['post_type']=='revision')
  2239. || $post_type == 'revision'
  2240. || get_post_meta($pidd, '_wp_trash_meta_status', true)
  2241. || ( isset($_GET['action']) && $_GET['action']=='restore')
  2242. /*|| $post_status == 'auto-draft'*/
  2243. ){
  2244. return;
  2245. }
  2246. // exception for auto-drafts - setting the right language
  2247. if(empty($_POST['icl_post_language']) && $post_status == 'auto-draft' && $this->get_current_language() != $this->get_default_language()){
  2248. $_POST['icl_post_language'] = $this->get_current_language();
  2249. }
  2250. // allow post arguments to be passed via wp_insert_post directly and not be expected on $_POST exclusively
  2251. $postvars = (array)$_POST;
  2252. foreach((array)$post as $k=>$v){
  2253. $postvars[$k] = $v;
  2254. }
  2255. if (!isset($postvars['post_type'])) {
  2256. $postvars['post_type'] = $post_type;
  2257. }
  2258. if(isset($postvars['action']) && $postvars['action']=='post-quickpress-publish'){
  2259. $post_id = $pidd;
  2260. $language_code = $this->get_default_language();
  2261. }elseif(isset($_GET['bulk_edit'])){
  2262. $post_id = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID={$pidd}");
  2263. }
  2264. else{
  2265. $post_id = isset($postvars['post_ID'])?$postvars['post_ID']:$pidd; //latter case for XML-RPC publishing
  2266. if(isset($postvars['icl_post_language'])){
  2267. $language_code = $postvars['icl_post_language'];
  2268. }elseif($_ldet = $this->get_element_language_details($post_id, 'post_' . $post_type)){
  2269. $language_code = $_ldet->language_code;
  2270. }else{
  2271. $language_code = $this->get_default_language(); //latter case for XML-RPC publishing
  2272. }
  2273. }
  2274. if(isset($postvars['action']) && $postvars['action']=='inline-save' || isset($_GET['bulk_edit']) || isset($_GET['doing_wp_cron']) || (isset($_GET['action']) && $_GET['action']=='untrash')){
  2275. $res = $wpdb->get_row("SELECT trid, language_code FROM {$wpdb->prefix}icl_translations WHERE element_id={$post_id} AND element_type LIKE 'post\\_%'");
  2276. $trid = $res->trid;
  2277. $language_code = $res->language_code;
  2278. }else{
  2279. if(isset($postvars['icl_trid'])){
  2280. $trid = @intval($postvars['icl_trid']);
  2281. }else{
  2282. $trid = $this->get_element_trid($post_id, 'post_' . $post->post_type);
  2283. }
  2284. // see if we have a "translation of" setting.
  2285. if(isset($postvars['icl_translation_of'])){
  2286. if(is_numeric($postvars['icl_translation_of'])){
  2287. $trid = $wpdb->get_var($wpdb->prepare("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", $postvars['icl_translation_of'], 'post_' . $post->post_type));
  2288. }else{
  2289. $trid = null;
  2290. }
  2291. }
  2292. }
  2293. $this->set_element_language_details($post_id, 'post_'.$post_type, $trid, $language_code);
  2294. if(!in_array($post_type, array('post','page')) && !$this->is_translated_post_type($post_type)){
  2295. return;
  2296. }
  2297. // used by the sync jobs
  2298. $translated_posts = $wpdb->get_col("
  2299. SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid='{$trid}' AND element_id<>{$post_id}");
  2300. // synchronize the page order for translations
  2301. if($trid && $this->settings['sync_page_ordering']){
  2302. $menu_order = $wpdb->escape($postvars['menu_order']);
  2303. if(!empty($translated_posts)){
  2304. $wpdb->query("UPDATE {$wpdb->posts} SET menu_order={$menu_order} WHERE ID IN (".join(',', $translated_posts).")");
  2305. }
  2306. }
  2307. // synchronize the page parent for translations
  2308. if($trid && $this->settings['sync_page_parent']){
  2309. $translations = $this->get_element_translations($trid, 'post_' . $postvars['post_type']);
  2310. foreach($translations as $target_lang => $target_details){
  2311. if($target_lang != $language_code){
  2312. if ($target_details->element_id) {
  2313. $this->fix_translated_parent($post_id, $target_details->element_id, $target_lang, $language_code);
  2314. // restore child-parent relationships
  2315. $children = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_parent={$target_details->element_id} AND post_type='page'");
  2316. foreach($children as $ch){
  2317. $ch_trid = $this->get_element_trid($ch, 'post_' . $postvars['post_type']);
  2318. $ch_translations = $this->get_element_translations($ch_trid, 'post_' . $postvars['post_type']);
  2319. if(isset($ch_translations[$language_code])){
  2320. $wpdb->update($wpdb->posts, array('post_parent'=>$post_id), array('ID'=>$ch_translations[$language_code]->element_id));
  2321. }
  2322. }
  2323. }
  2324. }
  2325. }
  2326. }
  2327. // synchronize the page template
  2328. if(isset($postvars['page_template']) && $trid && $postvars['post_type']=='page' && $this->settings['sync_page_template']){
  2329. if(!empty($translated_posts)){
  2330. foreach($translated_posts as $tp){
  2331. if($tp != $post_id){
  2332. update_post_meta($tp, '_wp_page_template', $postvars['page_template']);
  2333. }
  2334. }
  2335. }
  2336. }
  2337. // synchronize comment and ping status
  2338. if($trid && ($this->settings['sync_ping_status'] || $this->settings['sync_comment_status'])){
  2339. $arr = array();
  2340. if($this->settings['sync_comment_status']){
  2341. $arr['comment_status'] = $postvars['comment_status'];
  2342. }
  2343. if($this->settings['sync_ping_status']){
  2344. $arr['ping_status'] = $postvars['ping_status'];
  2345. }
  2346. if(!empty($arr)){
  2347. if(!empty($translated_posts)){
  2348. foreach($translated_posts as $tp){
  2349. if($tp != $post_id){
  2350. $wpdb->update($wpdb->posts, $arr, array('ID'=>$tp));
  2351. }
  2352. }
  2353. }
  2354. }
  2355. }
  2356. // copy custom fields from original
  2357. $translations = $this->get_element_translations($trid, 'post_' . $postvars['post_type']);
  2358. if (!empty($translations)) {
  2359. foreach($translations as $t) if($t->original){ $original_post_id = $t->element_id; break;}
  2360. // this runs only for translated documents
  2361. if($post_id != $original_post_id){
  2362. // get full list of custom fields and values for original document.
  2363. // using get_post_custom returns array of arrays - even for single value custom fields
  2364. $custom_fields_original = get_post_custom($original_post_id);
  2365. // get full list of custom fields and values for translated document. (this document)
  2366. $custom_fields_translation = get_post_custom($post_id);
  2367. // check each and every custom field that should be copied in the list of fields of
  2368. // the original document
  2369. foreach($custom_fields_original as $meta_key => $meta_values){
  2370. if(isset($this->settings['translation-management']['custom_fields_translation'][$meta_key])
  2371. && $this->settings['translation-management']['custom_fields_translation'][$meta_key] == 1){
  2372. // determine values that need to be deleted from the list of fields
  2373. // of the translated document
  2374. if(!empty($custom_fields_translation[$meta_key])){
  2375. $deleted_fields = array_diff($custom_fields_translation[$meta_key], $meta_values);
  2376. // delete values that exist on the translated document but not on the original document
  2377. foreach($deleted_fields as $meta_value){
  2378. delete_post_meta($post_id, $meta_key, $meta_value);
  2379. }
  2380. }
  2381. // if the list of values has 1 element run update
  2382. // this will either ADD or UPDATE the value on the translated document
  2383. if(count($meta_values) == 1){
  2384. update_post_meta($post_id, $meta_key, maybe_unserialize($meta_values[0]));;
  2385. // determine the list of added elements
  2386. }else{
  2387. // all fields are new
  2388. if(empty($custom_fields_translation[$meta_key])){
  2389. $added_fields = $meta_values;
  2390. // some fields are new
  2391. }else{
  2392. $added_fields = array_diff($meta_values, $custom_fields_translation[$meta_key]);
  2393. }
  2394. // run ADD on each element added
  2395. foreach($added_fields as $v){
  2396. add_post_meta($post_id, $meta_key, $v, true);
  2397. }
  2398. }
  2399. }
  2400. }
  2401. // NOTE: changing the value of 1 element of a multi-values custom field will trigger 1 DELETE and 1 ADD
  2402. }
  2403. }
  2404. //sync posts stickiness
  2405. if(isset($postvars['post_type']) && $postvars['post_type']=='post' && isset($postvars['action']) && $postvars['action']!='post-quickpress-publish' && $this->settings['sync_sticky_flag']){ //not for quick press
  2406. remove_filter('option_sticky_posts', array($this,'option_sticky_posts')); // remove filter used to get language relevant stickies. get them all
  2407. $sticky_posts = get_option('sticky_posts');
  2408. // get ids of othe translations
  2409. if($trid){
  2410. $translations = $wpdb->get_col($wpdb->prepare("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d", $trid));
  2411. }else{
  2412. $translations = array();
  2413. }
  2414. if(isset($postvars['sticky']) && $postvars['sticky'] == 'sticky'){
  2415. $sticky_posts = array_unique(array_merge($sticky_posts, $translations));
  2416. }else{
  2417. //makes sure translations are not set to sticky if this posts switched from sticky to not-sticky
  2418. $sticky_posts = array_diff($sticky_posts, $translations);
  2419. }
  2420. update_option('sticky_posts',$sticky_posts);
  2421. }
  2422. //sync private flag
  2423. if($this->settings['sync_private_flag']){
  2424. if($post_status=='private' && (empty($postvars['original_post_status']) || $postvars['original_post_status']!='private')){
  2425. if(!empty($translated_posts)){
  2426. foreach($translated_posts as $tp){
  2427. if($tp != $post_id){
  2428. $wpdb->update($wpdb->posts, array('post_status'=>'private'), array('ID'=>$tp));
  2429. }
  2430. }
  2431. }
  2432. }elseif($post_status!='private' && isset($postvars['original_post_status']) && $postvars['original_post_status']=='private'){
  2433. if(!empty($translated_posts)){
  2434. foreach($translated_posts as $tp){
  2435. if($tp != $post_id){
  2436. $wpdb->update($wpdb->posts, array('post_status'=>$post_status), array('ID'=>$tp));
  2437. }
  2438. }
  2439. }
  2440. }
  2441. }
  2442. //sync post format
  2443. if($this->settings['sync_post_format'] && function_exists('set_post_format')){
  2444. $format = get_post_format( $post_id );
  2445. if(!empty($translated_posts)){
  2446. foreach($translated_posts as $tp){
  2447. if($tp != $post_id){
  2448. set_post_format($tp, $format);
  2449. }
  2450. }
  2451. }
  2452. }
  2453. // sync taxonomies (ONE WAY)
  2454. if(!empty($this->settings['sync_post_taxonomies']) && $language_code == $this->get_default_language()){
  2455. $translatable_taxs = $this->get_translatable_taxonomies(true, $postvars['post_type']);
  2456. $all_taxs = get_object_taxonomies($postvars['post_type']);
  2457. if(!empty($all_taxs)){
  2458. $translations = $this->get_element_translations($trid, 'post_' . $postvars['post_type']);
  2459. foreach($all_taxs as $tt){
  2460. $terms = get_the_terms($post_id, $tt);
  2461. if(!empty($terms)){
  2462. foreach($translations as $target_lang=>$translation){
  2463. if($target_lang != $language_code){
  2464. $tax_sync = array();
  2465. foreach($terms as $term){
  2466. if(in_array($tt, $translatable_taxs)){
  2467. $term_id = icl_object_id($term->term_id, $tt, false, $target_lang);
  2468. }else{
  2469. $term_id = $term->term_id;
  2470. }
  2471. if($term_id){
  2472. $tax_sync[] = intval($term_id);
  2473. }
  2474. }
  2475. wp_set_object_terms($translation->element_id, $tax_sync, $tt, false);
  2476. }
  2477. }
  2478. }
  2479. }
  2480. }
  2481. }
  2482. // sync post dates
  2483. if(!empty($this->settings['sync_post_date'])){
  2484. if($language_code == $this->get_default_language()){
  2485. if(!empty($translated_posts)){
  2486. $post_date = $wpdb->get_var($wpdb->prepare("SELECT post_date FROM {$wpdb->posts} WHERE ID=%d", $post_id));
  2487. foreach($translated_posts as $tp){
  2488. if($tp != $post_id){
  2489. $wpdb->update($wpdb->posts, array('post_date'=>$post_date), array('ID'=>$tp));
  2490. }
  2491. }
  2492. }
  2493. }else{
  2494. if ( !is_null($trid) ){
  2495. $source_lang = isset($_GET['source_lang'])?$_GET['source_lang']:$this->get_default_language();
  2496. $original_id = $wpdb->get_var($wpdb->prepare("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND language_code=%s", $trid, $source_lang));
  2497. $post_date = $wpdb->get_var($wpdb->prepare("SELECT post_date FROM {$wpdb->posts} WHERE ID=%d", $original_id));
  2498. $wpdb->update($wpdb->posts, array('post_date'=>$post_date), array('ID'=>$post_id));
  2499. }
  2500. }
  2501. }
  2502. // new categories created inline go to the correct language
  2503. if(isset($postvars['post_category']) && is_array($postvars['post_category']) && $postvars['action']!='inline-save' && $postvars['icl_post_language'])
  2504. foreach($postvars['post_category'] as $cat){
  2505. $ttid = $wpdb->get_var("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id={$cat} AND taxonomy='category'");
  2506. $wpdb->update($wpdb->prefix.'icl_translations',
  2507. array('language_code'=>$postvars['icl_post_language']),
  2508. array('element_id'=>$ttid, 'element_type'=>'tax_category'));
  2509. }
  2510. if(isset($postvars['icl_tn_note'])){
  2511. update_post_meta($post_id, '_icl_translator_note', $postvars['icl_tn_note']);
  2512. }
  2513. //fix guid
  2514. if($this->settings['language_negotiation_type'] == 2 && $this->get_current_language() != $this->get_default_language()){
  2515. $guid = $this->convert_url(get_post_field( 'guid', $post_id ));
  2516. $wpdb->update($wpdb->posts, array('guid' => $guid), array('id' => $post_id));
  2517. }
  2518. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  2519. @icl_cache_clear($postvars['post_type'].'s_per_language');
  2520. }
  2521. function wp_unique_post_slug($slug, $post_ID, $post_status, $post_type, $post_parent){
  2522. if(!$this->is_translated_post_type($post_type) || empty($post_ID)) return $slug;
  2523. $post = get_post($post_ID);
  2524. if ( in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) ) )
  2525. return $slug;
  2526. global $wpdb, $wp_rewrite;
  2527. $feeds = $wp_rewrite->feeds;
  2528. if ( ! is_array( $feeds ) )
  2529. $feeds = array();
  2530. $post_language = $this->get_language_for_element($post_ID, 'post_' . $post_type);
  2531. if(isset($_POST['new_slug']) && $_POST['new_slug'] !== ''){
  2532. $slug = sanitize_title($_POST['new_slug'], $post->ID);
  2533. }elseif(isset($_POST['action']) && $_POST['action']=='inline-save'){
  2534. $slug = sanitize_title($_POST['post_name'], $post->ID);
  2535. }else{
  2536. $slug = sanitize_title($post->post_name ? $post->post_name : $post->post_title, $post->ID);
  2537. }
  2538. $hierarchical_post_types = get_post_types( array('hierarchical' => true) );
  2539. if ( in_array( $post_type, $hierarchical_post_types ) ) {
  2540. // Page slugs must be unique within their own trees. Pages are in a separate
  2541. // namespace than posts so page slugs are allowed to overlap post slugs.
  2542. $check_sql = "SELECT p.post_name
  2543. FROM $wpdb->posts p
  2544. JOIN {$wpdb->prefix}icl_translations t ON p.ID = t.element_id AND t.element_type = %s
  2545. WHERE p.post_name = %s AND p.post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' )
  2546. AND p.ID != %d AND p.post_parent = %d AND t.language_code = %s LIMIT 1";
  2547. $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, 'post_' . $post_type, $slug, $post_ID, $post_parent, $post_language) );
  2548. if ( $post_name_check || in_array( $slug, $feeds ) || preg_match( "@^($wp_rewrite->pagination_base)?\d+$@", $slug ) || apply_filters( 'wp_unique_post_slug_is_bad_hierarchical_slug', false, $slug, $post_type, $post_parent ) ) {
  2549. $suffix = 2;
  2550. do {
  2551. $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  2552. $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, 'post_' . $post_type, $alt_post_name, $post_ID, $post_parent, $post_language) );
  2553. $suffix++;
  2554. } while ( $post_name_check );
  2555. $slug = $alt_post_name;
  2556. }
  2557. } else {
  2558. // Post slugs must be unique across all posts.
  2559. $check_sql = "SELECT p.post_name
  2560. FROM $wpdb->posts p
  2561. JOIN {$wpdb->prefix}icl_translations t ON p.ID = t.element_id AND t.element_type = %s
  2562. WHERE p.post_name = %s AND p.post_type = %s AND p.ID != %d AND t.language_code = %s LIMIT 1";
  2563. $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, 'post_' . $post_type, $slug, $post_type, $post_ID, $post_language ) );
  2564. if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
  2565. $suffix = 2;
  2566. do {
  2567. $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  2568. $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, 'post_' . $post_type, $alt_post_name, $post_type, $post_ID, $post_language ) );
  2569. $suffix++;
  2570. } while ( $post_name_check );
  2571. $slug = $alt_post_name;
  2572. }
  2573. }
  2574. if(isset($_POST['new_slug'])){
  2575. $wpdb->update($wpdb->posts, array('post_name' => $slug), array('ID' => $post_ID));
  2576. }
  2577. return $slug;
  2578. }
  2579. function fix_translated_parent($original_id, $translated_id, $lang_code, $language_code){
  2580. global $wpdb;
  2581. $icl_post_type = isset($_POST['post_type']) ? 'post_' . $_POST['post_type'] : 'post_page';
  2582. $original_parent = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID = {$original_id} AND post_type = 'page'");
  2583. if (!is_null($original_parent)){
  2584. if($original_parent === '0'){
  2585. $parent_of_translated_id = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID = {$translated_id} AND post_type = 'page'");
  2586. $translations = $this->get_element_translations($this->get_element_trid($parent_of_translated_id,$icl_post_type),$icl_post_type);
  2587. if(isset($translations[$language_code])){
  2588. $wpdb->query("UPDATE {$wpdb->posts} SET post_parent='0' WHERE ID = ".$translated_id);
  2589. }
  2590. }else{
  2591. $trid = $this->get_element_trid($original_parent, $icl_post_type);
  2592. if($trid){
  2593. $translations = $this->get_element_translations($trid, $icl_post_type);
  2594. if (isset($translations[$lang_code])){
  2595. $current_parent = $wpdb->get_var("SELECT post_parent FROM {$wpdb->posts} WHERE ID = ".$translated_id);
  2596. if ($current_parent != $translations[$lang_code]->element_id){
  2597. $wpdb->query("UPDATE {$wpdb->posts} SET post_parent={$translations[$lang_code]->element_id} WHERE ID = ".$translated_id);
  2598. }
  2599. }
  2600. }
  2601. }
  2602. }
  2603. }
  2604. /*
  2605. function pre_update_post_meta($null, $object_id, $meta_key, $meta_value, $prev_value){
  2606. // if this is a translation and this custom field is set to be copied from the original
  2607. // make sure we're altering it's value in order to trigger the updated_post_meta action
  2608. // that allows WPML to copy everything
  2609. global $wpdb;
  2610. if(isset($this->settings['translation-management']['custom_fields_translation'][$meta_key]) && $this->settings['translation-management']['custom_fields_translation'][$meta_key] == 1 ){
  2611. $post = get_post($object_id);
  2612. $translated_docs = $this->get_translatable_documents();
  2613. if(!empty($translated_docs[$post->post_type])){
  2614. $trid = $this->get_element_trid($object_id, 'post_' . $post->post_type);
  2615. if($trid){
  2616. $translations = $this->get_element_translations($trid, 'post_' . $post->post_type);
  2617. foreach($translations as $t){
  2618. if($t->original){
  2619. $original_id = $t->element_id;
  2620. }
  2621. }
  2622. if($original_id != $object_id){
  2623. $wpdb->update($wpdb->postmeta, array('meta_value'=>!$meta_value), array('post_id'=>$object_id, 'meta_key'=>$meta_key));
  2624. wp_cache_delete($object_id, 'post_meta');
  2625. }
  2626. }
  2627. }
  2628. }
  2629. return null; // allow further execution
  2630. }
  2631. */
  2632. function update_post_meta($meta_id, $object_id, $meta_key, $_meta_value){
  2633. static $_recur_control_flag = 0; // avoid recursion
  2634. if($_recur_control_flag) return;
  2635. $_recur_control_flag = 1; // avoid recursion (dont return before $_recur_control_flag = 0;)
  2636. if(isset($this->settings['translation-management']['custom_fields_translation'][$meta_key]) && $this->settings['translation-management']['custom_fields_translation'][$meta_key] == 1 ){
  2637. $post = get_post($object_id);
  2638. $translated_docs = $this->get_translatable_documents();
  2639. if(!empty($translated_docs[$post->post_type])){
  2640. $trid = $this->get_element_trid($object_id, 'post_' . $post->post_type);
  2641. if($trid){
  2642. $translations = $this->get_element_translations($trid, 'post_' . $post->post_type);
  2643. foreach($translations as $t){
  2644. if($t->original){
  2645. $original_id = $t->element_id;
  2646. }
  2647. }
  2648. if($original_id == $object_id){
  2649. foreach($translations as $t){
  2650. if(!$t->original){
  2651. //update_post_meta($t->element_id, $meta_key, $_meta_value);
  2652. $original_fields = get_post_meta($object_id, $meta_key);
  2653. $copied_fields = get_post_meta($t->element_id, $meta_key);
  2654. if(count($original_fields) > 1 || count($copied_fields) > 1){
  2655. $deleted_fields = array_diff($copied_fields, $original_fields);
  2656. foreach($original_fields as $field){
  2657. if(!in_array($field, $copied_fields)){
  2658. add_post_meta($t->element_id, $meta_key, $field);
  2659. }
  2660. }
  2661. foreach($deleted_fields as $field){
  2662. delete_post_meta($t->element_id, $meta_key, $field);
  2663. }
  2664. }else{
  2665. update_post_meta($t->element_id, $meta_key, $_meta_value);
  2666. }
  2667. }
  2668. }
  2669. }else{
  2670. $original_meta = get_post_meta($original_id, $meta_key, true);
  2671. if(false !== $original_meta){
  2672. //update_post_meta($object_id, $meta_key, $original_meta);
  2673. $original_fields = get_post_meta($original_id, $meta_key);
  2674. $copied_fields = get_post_meta($object_id, $meta_key);
  2675. if(count($original_fields) > 1 || count($copied_fields) > 1){
  2676. $deleted_fields = array_diff($copied_fields, $original_fields);
  2677. foreach($original_fields as $field){
  2678. if(!in_array($field, $copied_fields)){
  2679. add_post_meta($object_id, $meta_key, $field);
  2680. }
  2681. }
  2682. foreach($deleted_fields as $field){
  2683. delete_post_meta($object_id, $meta_key, $field);
  2684. }
  2685. }else{
  2686. update_post_meta($object_id, $meta_key, $_meta_value);
  2687. }
  2688. }else{
  2689. delete_post_meta($object_id, $meta_key);
  2690. }
  2691. }
  2692. }
  2693. }
  2694. }
  2695. $_recur_control_flag = 0;
  2696. }
  2697. function delete_post_meta($meta_id){
  2698. static $_recur_control_flag = 0; // avoid recursion
  2699. if($_recur_control_flag) return;
  2700. $_recur_control_flag = 1; // avoid recursion (dont return before $_recur_control_flag = 0;)
  2701. if(!function_exists('get_post_meta_by_id')){
  2702. require_once ABSPATH .'wp-admin/includes/post.php';
  2703. }
  2704. $meta = get_post_meta_by_id($meta_id);
  2705. if($meta){
  2706. if(isset($this->settings['translation-management']['custom_fields_translation'][$meta->meta_key])
  2707. && $this->settings['translation-management']['custom_fields_translation'][$meta->meta_key] == 1 ){
  2708. $post = get_post($meta->post_id);
  2709. $translated_docs = $this->get_translatable_documents();
  2710. if(!empty($translated_docs[$post->post_type])){
  2711. $trid = $this->get_element_trid($meta->post_id, 'post_' . $post->post_type);
  2712. if($trid){
  2713. $translations = $this->get_element_translations($trid, 'post_' . $post->post_type);
  2714. foreach($translations as $t){
  2715. if($t->original){
  2716. $original_id = $t->element_id;
  2717. }
  2718. }
  2719. if($original_id == $meta->post_id){
  2720. foreach($translations as $t){
  2721. if(!$t->original){
  2722. delete_post_meta($t->element_id, $meta->meta_key, $meta->meta_value);
  2723. }
  2724. }
  2725. }
  2726. }
  2727. }
  2728. }
  2729. }
  2730. $_recur_control_flag = 0;
  2731. }
  2732. /*
  2733. function get_post_metadata_filter($null, $object_id, $meta_key, $single){
  2734. $meta_value = null;
  2735. if(isset($this->settings['translation-management']['custom_fields_translation'][$meta_key]) && $this->settings['translation-management']['custom_fields_translation'][$meta_key] == 1 ){
  2736. if($this->get_current_language() == $this->get_default_language()) return;
  2737. global $pagenow, $wpdb;
  2738. static $_recur_control_flag = 0;
  2739. if($_recur_control_flag) return;
  2740. $_recur_control_flag = 1; // avoid recursion (dont return before $_recur_control_flag = 0;)
  2741. if($pagenow == 'post-new.php'){
  2742. $original_id = $wpdb->get_var($wpdb->prepare("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND language_code=%s", $_GET['trid'], $_GET['source_lang']));
  2743. }else{
  2744. $post_type = $wpdb->get_var($wpdb->prepare("SELECT post_type FROM {$wpdb->posts} WHERE ID=%d", $object_id));
  2745. $original_id = icl_object_id($object_id, $post_type, false, $this->get_default_language());
  2746. }
  2747. $meta_value = get_post_meta($original_id, $meta_key, $single);
  2748. $_recur_control_flag = 0;
  2749. }
  2750. return $meta_value;
  2751. }
  2752. */
  2753. function delete_post_actions($post_id){
  2754. global $wpdb;
  2755. static $deleted_posts;
  2756. if(isset($deleted_posts[$post_id])){
  2757. return; // avoid infinite loop
  2758. }
  2759. $post_type = $wpdb->get_var("SELECT post_type FROM {$wpdb->posts} WHERE ID={$post_id}");
  2760. if(empty($deleted_posts) && $this->settings['sync_delete']){
  2761. $trid = $this->get_element_trid($post_id, 'post_' . $post_type);
  2762. $translations = $this->get_element_translations($trid, 'post_' . $post_type);
  2763. foreach($translations as $t){
  2764. $deleted_posts[] = $post_id;
  2765. wp_delete_post($t->element_id);
  2766. }
  2767. }
  2768. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_translations WHERE element_type='post_{$post_type}' AND element_id='{$post_id}' LIMIT 1");
  2769. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  2770. icl_cache_clear($post_type.'s_per_language');
  2771. }
  2772. function trash_post_actions($post_id){
  2773. if($this->settings['sync_delete']){
  2774. global $wpdb;
  2775. static $trashed_posts = array();
  2776. $post_type = $wpdb->get_var("SELECT post_type FROM {$wpdb->posts} WHERE ID={$post_id}");
  2777. if(isset($trashed_posts[$post_id])){
  2778. return; // avoid infinite loop
  2779. }
  2780. $trashed_posts[$post_id] = $post_id;
  2781. $trid = $this->get_element_trid($post_id, 'post_' . $post_type);
  2782. $translations = $this->get_element_translations($trid, 'post_' . $post_type);
  2783. foreach($translations as $t){
  2784. if($t->element_id != $post_id){
  2785. wp_trash_post($t->element_id);
  2786. }
  2787. }
  2788. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  2789. icl_cache_clear($post_type.'s_per_language');
  2790. }
  2791. }
  2792. function untrashed_post_actions($post_id){
  2793. if($this->settings['sync_delete']){
  2794. global $wpdb;
  2795. static $untrashed_posts = array();
  2796. $post_type = $wpdb->get_var("SELECT post_type FROM {$wpdb->posts} WHERE ID={$post_id}");
  2797. if(isset($untrashed_posts[$post_id])){
  2798. return; // avoid infinite loop
  2799. }
  2800. $untrashed_posts[$post_id] = $post_id;
  2801. $trid = $this->get_element_trid($post_id, 'post_' . $post_type);
  2802. $translations = $this->get_element_translations($trid, 'post_' . $post_type);
  2803. foreach($translations as $t){
  2804. if($t->element_id != $post_id){
  2805. wp_untrash_post($t->element_id);
  2806. }
  2807. }
  2808. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  2809. icl_cache_clear($post_type.'s_per_language');
  2810. }
  2811. }
  2812. function validate_taxonomy_input($input){
  2813. global $wpdb;
  2814. static $runonce;
  2815. if(empty($runonce)){
  2816. $post_language = isset($_POST['icl_post_language']) ? $_POST['icl_post_language'] : $this->get_current_language();
  2817. if(!empty($input) && is_array($input))
  2818. foreach($input as $taxonomy => $values){
  2819. if(is_string($values)){ // only not-hierarchical
  2820. $values = array_map('trim', explode(',', $values));
  2821. foreach($values as $k => $term){
  2822. // if the term exists in another language, apply the language suffix
  2823. $term_info = term_exists($term, $taxonomy);
  2824. if($term_info){
  2825. $term_language = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM {$wpdb->prefix}icl_translations
  2826. WHERE element_type=%s AND element_id=%d", 'tax_' . $taxonomy, $term_info['term_taxonomy_id']));
  2827. if($term_language && $term_language != $post_language){
  2828. $term = $term . ' @' . $post_language;
  2829. }
  2830. }
  2831. $values[$k] = $term;
  2832. }
  2833. $values = join(',', $values);
  2834. $input[$taxonomy] = $values;
  2835. }
  2836. }
  2837. $runonce = true;
  2838. }
  2839. return $input;
  2840. }
  2841. function get_element_translations($trid, $el_type='post_post', $skip_empty = false){
  2842. global $wpdb;
  2843. $translations = array();
  2844. $sel_add = '';
  2845. $where_add = '';
  2846. if($trid){
  2847. if(0 === strpos($el_type, 'post_')){
  2848. $sel_add = ', p.post_title, p.post_status';
  2849. $join_add = " LEFT JOIN {$wpdb->posts} p ON t.element_id=p.ID";
  2850. $groupby_add = "";
  2851. if(!is_admin()){
  2852. $where_add .= " AND (";
  2853. $where_add .= "p.post_status = 'publish'";
  2854. if($uid = get_current_user_id()){
  2855. $where_add .= " OR (post_status in ('draft', 'private') AND post_author = {$uid})";
  2856. }
  2857. $where_add .= ") ";
  2858. }
  2859. }elseif(preg_match('#^tax_(.+)$#',$el_type)){
  2860. $sel_add = ', tm.name, tm.term_id, COUNT(tr.object_id) AS instances';
  2861. $join_add = " LEFT JOIN {$wpdb->term_taxonomy} tt ON t.element_id=tt.term_taxonomy_id
  2862. LEFT JOIN {$wpdb->terms} tm ON tt.term_id = tm.term_id
  2863. LEFT JOIN {$wpdb->term_relationships} tr ON tr.term_taxonomy_id=tt.term_taxonomy_id
  2864. ";
  2865. $groupby_add = "GROUP BY tm.term_id";
  2866. }
  2867. $where_add .= " AND t.trid='{$trid}'";
  2868. $query = "
  2869. SELECT t.translation_id, t.language_code, t.element_id, t.source_language_code IS NULL AS original {$sel_add}
  2870. FROM {$wpdb->prefix}icl_translations t
  2871. {$join_add}
  2872. WHERE 1 {$where_add}
  2873. {$groupby_add}
  2874. ";
  2875. $ret = $wpdb->get_results($query);
  2876. foreach($ret as $t){
  2877. if((preg_match('#^tax_(.+)$#',$el_type))
  2878. && $t->instances==0 && !_icl_tax_has_objects_recursive($t->element_id)
  2879. && $skip_empty) continue;
  2880. $translations[$t->language_code] = $t;
  2881. }
  2882. }
  2883. return $translations;
  2884. }
  2885. function get_element_trid($element_id, $el_type='post_post'){
  2886. global $wpdb;
  2887. return $wpdb->get_var("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id='{$element_id}' AND element_type='{$el_type}'");
  2888. }
  2889. function get_language_for_element($element_id, $el_type='post_post'){
  2890. global $wpdb;
  2891. return $wpdb->get_var("SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_id='{$element_id}' AND element_type='{$el_type}'");
  2892. }
  2893. function get_elements_without_translations($el_type, $target_lang, $source_lang){
  2894. global $wpdb;
  2895. // first get all the trids for the target languages
  2896. // These will be the trids that we don't want.
  2897. $sql = "SELECT
  2898. trid
  2899. FROM
  2900. {$wpdb->prefix}icl_translations
  2901. WHERE
  2902. language_code = '{$target_lang}'
  2903. AND element_type = '{$el_type}'
  2904. ";
  2905. $trids_for_target = $wpdb->get_col($sql);
  2906. if (sizeof($trids_for_target) > 0) {
  2907. $trids_for_target = join(',', $trids_for_target);
  2908. $not_trids = 'AND trid NOT IN (' .$trids_for_target . ')';
  2909. } else {
  2910. $not_trids = '';
  2911. }
  2912. $join = $where = '';
  2913. // exclude trashed posts
  2914. if(0 === strpos($el_type, 'post_')){
  2915. $join .= " JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->prefix}icl_translations.element_id";
  2916. $where .= " AND {$wpdb->posts}.post_status <> 'trash' AND {$wpdb->posts}.post_status <> 'auto-draft'";
  2917. }
  2918. // Now get all the elements that are in the source language that
  2919. // are not already translated into the target language.
  2920. $sql = "SELECT
  2921. element_id
  2922. FROM
  2923. {$wpdb->prefix}icl_translations
  2924. {$join}
  2925. WHERE
  2926. language_code = '{$source_lang}'
  2927. {$not_trids}
  2928. AND element_type= '{$el_type}'
  2929. {$where}
  2930. ";
  2931. return $wpdb->get_col($sql);
  2932. }
  2933. function get_posts_without_translations($selected_language, $default_language, $post_type='post_post') {
  2934. global $wpdb;
  2935. $untranslated_ids = $this->get_elements_without_translations($post_type, $selected_language, $default_language);
  2936. /* removed - we're already getting these by type */
  2937. /*
  2938. if (sizeof($untranslated_ids)) {
  2939. // filter for "page" or "post"
  2940. $ids = join(',',$untranslated_ids);
  2941. $type = preg_replace('#^post_#','',$post_type);
  2942. $untranslated_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE ID IN({$ids}) AND post_type = '{$type}' AND post_status <> 'auto-draft'");
  2943. }
  2944. */
  2945. $untranslated = array();
  2946. foreach ($untranslated_ids as $id) {
  2947. $untranslated[$id] = $wpdb->get_var("SELECT post_title FROM {$wpdb->prefix}posts WHERE ID = {$id}");
  2948. }
  2949. return $untranslated;
  2950. }
  2951. function meta_box($post){
  2952. global $wpdb, $wp_post_types, $iclTranslationManagement;
  2953. if(in_array($post->post_type, array_keys($this->get_translatable_documents()))){
  2954. $active_languages = $this->get_active_languages();
  2955. $default_language = $this->get_default_language();
  2956. if($post->ID && $post->post_status != 'auto-draft'){
  2957. $res = $this->get_element_language_details($post->ID, 'post_'.$post->post_type);
  2958. $trid = @intval($res->trid);
  2959. if($trid){
  2960. $element_lang_code = $res->language_code;
  2961. }else{
  2962. $translation_id = $this->set_element_language_details($post->ID,'post_'.$post->post_type,null, $this->get_current_language());
  2963. $trid = $wpdb->get_var($wpdb->prepare("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE translation_id=%d", $translation_id));
  2964. $element_lang_code = $this->get_current_language();
  2965. }
  2966. }else{
  2967. $trid = isset($_GET['trid']) ? intval($_GET['trid']) : false;
  2968. $element_lang_code = isset($_GET['lang']) ? strip_tags($_GET['lang']) : $this->get_current_language();
  2969. }
  2970. $translations = array();
  2971. if($trid){
  2972. $translations = $this->get_element_translations($trid, 'post_'.$post->post_type);
  2973. }
  2974. $selected_language = $element_lang_code?$element_lang_code:$this->get_current_language();
  2975. if(isset($_GET['lang'])){
  2976. $_selected_language = strip_tags($_GET['lang']);
  2977. }else{
  2978. $_selected_language = $selected_language;
  2979. }
  2980. if($_selected_language != $default_language){
  2981. $untranslated = $this->get_posts_without_translations($_selected_language, $default_language, 'post_' . $post->post_type);
  2982. }else{
  2983. $untranslated = array();
  2984. }
  2985. $source_language = isset($_GET['source_lang']) ? $_GET['source_lang'] : false;
  2986. //globalize some variables to make them available through hooks
  2987. global $icl_meta_box_globals;
  2988. $icl_meta_box_globals = array(
  2989. 'active_languages' => $active_languages,
  2990. 'translations' => $translations,
  2991. 'selected_language' => $selected_language
  2992. );
  2993. include ICL_PLUGIN_PATH . '/menu/post-menu.php';
  2994. }
  2995. }
  2996. function icl_get_metabox_states() {
  2997. global $icl_meta_box_globals, $wpdb;
  2998. $translation = false;
  2999. $source_id = null;
  3000. $translated_id = null;
  3001. if (sizeof($icl_meta_box_globals['translations']) > 0) {
  3002. if (!isset($icl_meta_box_globals['translations'][$icl_meta_box_globals['selected_language']])) {
  3003. // We are creating a new translation
  3004. $translation = true;
  3005. // find the original
  3006. foreach ($icl_meta_box_globals['translations'] as $trans_data) {
  3007. if ($trans_data->original == '1') {
  3008. $source_id = $trans_data->element_id;
  3009. break;
  3010. }
  3011. }
  3012. } else {
  3013. $trans_data = $icl_meta_box_globals['translations'][$icl_meta_box_globals['selected_language']];
  3014. // see if this is an original or a translation.
  3015. if ($trans_data->original == '0') {
  3016. // double check that it's not the original
  3017. // This is because the source_language_code field in icl_translations is not always being set to null.
  3018. $source_language_code = $wpdb->get_var("SELECT source_language_code FROM {$wpdb->prefix}icl_translations WHERE translation_id = $trans_data->translation_id");
  3019. $translation = !($source_language_code == "" || $source_language_code == null);
  3020. if ($translation) {
  3021. $source_id = $icl_meta_box_globals['translations'][$source_language_code]->element_id;
  3022. $translated_id = $trans_data->element_id;
  3023. } else {
  3024. $source_id = $trans_data->element_id;
  3025. }
  3026. } else {
  3027. $source_id = $trans_data->element_id;
  3028. }
  3029. }
  3030. }
  3031. return array($translation, $source_id, $translated_id);
  3032. }
  3033. function meta_box_config($post){
  3034. global $wpdb, $wp_post_types, $iclTranslationManagement;
  3035. global $wp_taxonomies, $wp_post_types;
  3036. echo '<div class="icl_form_success" style="display:none">'.__('Settings saved', 'sitepress').'</div>';
  3037. $cp_editable = false;
  3038. if(!in_array($post->post_type, array('post', 'page'))){
  3039. if(!isset($iclTranslationManagement->settings['custom_types_readonly_config'][$post->post_type])
  3040. || $iclTranslationManagement->settings['custom_types_readonly_config'][$post->post_type] !== 0){
  3041. if(in_array($post->post_type, array_keys($this->get_translatable_documents()))){
  3042. $checked = ' checked="checked"';
  3043. $rdisabled = isset($iclTranslationManagement->settings['custom_types_readonly_config'][$post->post_type]) ? 'disabled="disabled"':'';
  3044. }else{
  3045. $checked = $rdisabled = '';
  3046. }
  3047. if(!$rdisabled){
  3048. $cp_editable = true;
  3049. }
  3050. echo '<br style="line-height:8px;" /><label><input id="icl_make_translatable" type="checkbox" value="'.$post->post_type.'"'.$checked . $rdisabled.'/>&nbsp;' .
  3051. sprintf(__("Make '%s' translatable", 'sitepress'), $wp_post_types[$post->post_type]->labels->name) . '</label><br style="line-height:8px;" />';
  3052. }
  3053. }else{
  3054. echo '<input id="icl_make_translatable" type="checkbox" checked="checked" value="'.$post->post_type.'" style="display:none" />';
  3055. $checked = true;
  3056. }
  3057. echo '<br clear="all" /><span id="icl_mcs_details">';
  3058. if($checked){
  3059. //echo '<div style="width:49%;float:left;min-width:265px;margin-right:5px;margin-top:3px;">';
  3060. $ctaxonomies = array_diff(get_object_taxonomies($post->post_type), array('post_tag','category', 'nav_menu', 'link_category', 'post_format'));
  3061. if(!empty($ctaxonomies)){
  3062. ?>
  3063. <table class="widefat">
  3064. <thead>
  3065. <tr>
  3066. <th colspan="2"><?php _e('Custom taxonomies', 'sitepress'); ?></th>
  3067. </tr>
  3068. </thead>
  3069. <tbody>
  3070. <?php foreach($ctaxonomies as $ctax): ?>
  3071. <?php
  3072. $checked1 = !empty($this->settings['taxonomies_sync_option'][$ctax]) ? ' checked="checked"' : '';
  3073. $checked0 = empty($this->settings['taxonomies_sync_option'][$ctax]) ? ' checked="checked"' : '';
  3074. ?>
  3075. <tr>
  3076. <td><?php echo $wp_taxonomies[$ctax]->labels->name ?></td>
  3077. <td align="right">
  3078. <label><input name="icl_mcs_custom_taxs_<?php echo $ctax ?>" class="icl_mcs_custom_taxs" type="radio" value="<?php echo $ctax ?>" <?php echo $checked1; ?> />&nbsp;<?php _e('Translate', 'sitepress')?></label>
  3079. <label><input name="icl_mcs_custom_taxs_<?php echo $ctax ?>" type="radio" value="0" <?php echo $checked0; ?> />&nbsp;<?php _e('Do nothing', 'sitepress')?></label>
  3080. </td>
  3081. </tr>
  3082. <?php endforeach; ?>
  3083. </tbody>
  3084. </table>
  3085. <br />
  3086. <?php
  3087. }
  3088. //echo '</div><div style="width:50%;float:left;min-width:265px;margin-top:3px;">';
  3089. if(defined('WPML_TM_VERSION')){
  3090. $custom_keys = (array)get_post_custom_keys($post->ID);
  3091. $cf_keys_exceptions = array('_edit_last', '_edit_lock', '_wp_page_template', '_wp_attachment_metadata', '_icl_translator_note', '_alp_processed', '_pingme', '_encloseme', '_icl_lang_duplicate_of');
  3092. $custom_keys = array_diff($custom_keys, $cf_keys_exceptions);
  3093. $cf_settings_ro = (array)$iclTranslationManagement->settings['custom_fields_readonly_config'];
  3094. $cf_settings = $iclTranslationManagement->settings['custom_fields_translation'];
  3095. if(!empty($custom_keys)){
  3096. ?>
  3097. <table class="widefat">
  3098. <thead>
  3099. <tr>
  3100. <th colspan="2"><?php _e('Custom fields', 'sitepress'); ?></th>
  3101. </tr>
  3102. </thead>
  3103. <tbody>
  3104. <?php
  3105. foreach($custom_keys as $cfield) {
  3106. if (empty($cf_settings[$cfield]) || $cf_settings[$cfield] != 3) {
  3107. $rdisabled = in_array($cfield, $cf_settings_ro) ? 'disabled="disabled"' : '';
  3108. $checked0 = empty($cf_settings[$cfield]) ? ' checked="checked"' : '';
  3109. $checked1 = isset($cf_settings[$cfield]) && $cf_settings[$cfield]==1 ? ' checked="checked"' : '';
  3110. $checked2 = isset($cf_settings[$cfield]) && $cf_settings[$cfield]==2 ? ' checked="checked"' : '';
  3111. ?>
  3112. <tr>
  3113. <td><?php echo $cfield; ?></td>
  3114. <td align="right">
  3115. <label><input class="icl_mcs_cfs" name="icl_mcs_cf_<?php echo base64_encode($cfield); ?> " type="radio" value="0" <?php echo $rdisabled.$checked0 ?> />&nbsp;<?php _e("Don't translate", 'sitepress') ?></label>
  3116. <label><input class="icl_mcs_cfs" name="icl_mcs_cf_<?php echo base64_encode($cfield); ?> " type="radio" value="1" <?php echo $rdisabled.$checked1 ?> />&nbsp;<?php _e("Copy", 'sitepress') ?></label>
  3117. <label><input class="icl_mcs_cfs" name="icl_mcs_cf_<?php echo base64_encode($cfield); ?> " type="radio" value="2" <?php echo $rdisabled.$checked2 ?> />&nbsp;<?php _e("Translate", 'sitepress') ?></label>
  3118. </td>
  3119. </tr>
  3120. <?php
  3121. }
  3122. }
  3123. ?>
  3124. </tbody>
  3125. </table>
  3126. <br />
  3127. <?php
  3128. }
  3129. }
  3130. //echo '</div><br clear="all" />';
  3131. if(!empty($ctaxonomies) || !empty($custom_keys)){
  3132. echo '<small>' . __('Note: Custom taxonomies and custom fields are shared across different post types.', 'sitepress') . '</small>';
  3133. }
  3134. }
  3135. echo '</span>';
  3136. if($cp_editable || !empty($ctaxonomies) || !empty($custom_keys)){
  3137. echo '<p class="submit" style="margin:0;padding:0"><input class="button-secondary" id="icl_make_translatable_submit" type="button" value="'.__('Apply', 'sitepress').'" /></p><br clear="all" />';
  3138. wp_nonce_field('icl_mcs_inline_nonce', '_icl_nonce_imi');
  3139. }else{
  3140. _e('Nothing to configure.', 'sitepress');
  3141. }
  3142. }
  3143. function pre_get_posts($wpq){
  3144. // case of internal links list
  3145. //
  3146. if(isset($_POST['action']) && 'wp-link-ajax' == $_POST['action']){
  3147. if(!empty($_SERVER['HTTP_REFERER'])){
  3148. $parts = parse_url($_SERVER['HTTP_REFERER']);
  3149. parse_str(strval($parts['query']), $query);
  3150. $lang = isset($query['lang']) ? $query['lang'] : $this->get_default_language();
  3151. }else $lang = $this->get_default_language();
  3152. $this->this_lang = $lang;
  3153. $wpq->query_vars['suppress_filters'] = false;
  3154. }
  3155. return $wpq;
  3156. }
  3157. function posts_join_filter($join){
  3158. global $wpdb, $pagenow, $wp_taxonomies;
  3159. //exceptions
  3160. if(isset($_POST['wp-preview']) && $_POST['wp-preview']=='dopreview' || is_preview()){
  3161. $is_preview = true;
  3162. }else{
  3163. $is_preview = false;
  3164. }
  3165. if($pagenow=='upload.php' || $pagenow=='media-upload.php' || is_attachment() || $is_preview){
  3166. return $join;
  3167. }
  3168. // determine post type
  3169. $db = debug_backtrace();
  3170. foreach($db as $o){
  3171. if($o['function']=='apply_filters_ref_array' && $o['args'][0]=='posts_join'){
  3172. $post_type = $wpdb->escape($o['args'][1][1]->query_vars['post_type']);
  3173. break;
  3174. }
  3175. }
  3176. if($post_type == 'any' || 'all' == $this->this_lang){
  3177. $ljoin = "LEFT";
  3178. }else{
  3179. $ljoin = "";
  3180. }
  3181. if(is_array($post_type)){
  3182. $ptypes = array();
  3183. foreach($post_type as $ptype){
  3184. if($this->is_translated_post_type($ptype)){
  3185. $ptypes[] = $wpdb->escape('post_' . $ptype);
  3186. }
  3187. }
  3188. if(!empty($ptypes)){
  3189. $join .= " {$ljoin} JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->posts}.ID = t.element_id
  3190. AND t.element_type IN ('".join("','", $ptypes)."') JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active=1";
  3191. }
  3192. }elseif($post_type){
  3193. if($this->is_translated_post_type($post_type)){
  3194. $join .= " {$ljoin} JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->posts}.ID = t.element_id
  3195. AND t.element_type = 'post_{$post_type}' JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active=1";
  3196. }elseif($post_type == 'any'){
  3197. $join .= " {$ljoin} JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->posts}.ID = t.element_id
  3198. AND t.element_type LIKE 'post\\_%' {$ljoin} JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active=1";
  3199. }
  3200. }else{
  3201. if(is_tax()){
  3202. $tax = get_query_var('taxonomy');
  3203. $ttypes = $wp_taxonomies[$tax]->object_type;
  3204. foreach($ttypes as $k=>$v){
  3205. if(!$this->is_translated_post_type($v)) unset($ttypes[$k]);
  3206. }
  3207. }else{
  3208. $ttypes = array_keys($this->get_translatable_documents(false));
  3209. }
  3210. if(!empty($ttypes)){
  3211. foreach($ttypes as $k=>$v) $ttypes[$k] = 'post_' . $v;
  3212. $post_types = "'" . join("','",$ttypes) . "'";
  3213. $join .= " {$ljoin} JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->posts}.ID = t.element_id
  3214. AND t.element_type IN ({$post_types}) JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active=1";
  3215. }
  3216. }
  3217. return $join;
  3218. }
  3219. function posts_where_filter($where){
  3220. global $wpdb, $pagenow, $wp_taxonomies;
  3221. //exceptions
  3222. //$post_type = get_query_var('post_type');
  3223. // determine post type
  3224. $db = debug_backtrace();
  3225. foreach($db as $o){
  3226. if($o['function']=='apply_filters_ref_array' && $o['args'][0]=='posts_where'){
  3227. $post_type = $o['args'][1][1]->query_vars['post_type'];
  3228. break;
  3229. }
  3230. }
  3231. // case of taxonomy archive
  3232. if(empty($post_type) && is_tax()){
  3233. $tax = get_query_var('taxonomy');
  3234. $post_type = $wp_taxonomies[$tax]->object_type;
  3235. foreach($post_type as $k=>$v){
  3236. if(!$this->is_translated_post_type($v)) unset($post_type[$k]);
  3237. }
  3238. if(empty($post_type)) return $where; // don't filter
  3239. }
  3240. if(!$post_type) $post_type = 'post';
  3241. if(is_array($post_type) && !empty($post_type)){
  3242. $none_translated = true;
  3243. foreach($post_type as $ptype){
  3244. if($this->is_translated_post_type($ptype)){
  3245. $none_translated = false;
  3246. }
  3247. }
  3248. if($none_translated) return $where;
  3249. }else{
  3250. if(!$this->is_translated_post_type($post_type) && 'any' != $post_type){
  3251. return $where;
  3252. }
  3253. }
  3254. if(isset($_POST['wp-preview']) && $_POST['wp-preview']=='dopreview' || is_preview()){
  3255. $is_preview = true;
  3256. }else{
  3257. $is_preview = false;
  3258. }
  3259. if($pagenow=='upload.php' || $pagenow=='media-upload.php' || is_attachment() || $is_preview){
  3260. return $where;
  3261. }
  3262. if('all' != $this->this_lang){
  3263. if('any' == $post_type){
  3264. $cond = " AND (t.language_code='{$wpdb->escape($this->get_current_language())}' OR t.language_code IS NULL )";
  3265. }else{
  3266. $cond = " AND t.language_code='{$wpdb->escape($this->get_current_language())}'";
  3267. }
  3268. }else{
  3269. $cond = '';
  3270. }
  3271. $where .= $cond;
  3272. return $where;
  3273. }
  3274. function comment_feed_join($join){
  3275. global $wpdb, $wp_query;
  3276. $type = $wp_query->query_vars['post_type'] ? $wpdb->escape($wp_query->query_vars['post_type']) : 'post';
  3277. $wp_query->query_vars['is_comment_feed'] = true;
  3278. $join .= " JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->comments}.comment_post_ID = t.element_id
  3279. AND t.element_type='post_{$type}' AND t.language_code='{$wpdb->escape($this->this_lang)}' ";
  3280. return $join;
  3281. }
  3282. function comments_clauses($clauses, $obj){
  3283. global $wpdb;
  3284. if(isset($obj->query_vars['post_id'])) $post_id = $obj->query_vars['post_id'];
  3285. elseif(isset($obj->query_vars['post_ID'])) $post_id = $obj->query_vars['post_ID'];
  3286. if(!empty($post_id)){
  3287. $post = get_post($post_id);
  3288. if(!$this->is_translated_post_type($post->post_type)){
  3289. return $clauses;
  3290. }
  3291. }
  3292. if($this->get_current_language() != 'all'){
  3293. $clauses['join'] .= " JOIN {$wpdb->prefix}icl_translations icltr1 ON
  3294. icltr1.element_id = {$wpdb->comments}.comment_ID
  3295. JOIN {$wpdb->prefix}icl_translations icltr2 ON
  3296. icltr2.element_id = {$wpdb->comments}.comment_post_ID
  3297. ";
  3298. $clauses['where'] .= " AND icltr1.element_type = 'comment'
  3299. AND icltr1.language_code = '".$this->get_current_language()."'
  3300. AND icltr2.language_code = '".$this->get_current_language()."'
  3301. AND icltr2.element_type LIKE 'post\\_%' ";
  3302. }
  3303. return $clauses;
  3304. }
  3305. function language_filter(){
  3306. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  3307. global $wpdb, $pagenow;
  3308. $type = isset($_GET['post_type'])?$_GET['post_type']:'post';
  3309. if(!in_array($type, array('post','page')) && !in_array($type, array_keys($this->get_translatable_documents()))){
  3310. return;
  3311. }
  3312. $active_languages = $this->get_active_languages();
  3313. $post_status = get_query_var('post_status');
  3314. $langs = icl_cache_get($type.'s_per_language#' . $post_status);
  3315. if(!$langs){
  3316. $extra_cond = "";
  3317. if($post_status){
  3318. $extra_cond .= " AND post_status = '" . $post_status . "'";
  3319. }
  3320. if($post_status != 'trash'){
  3321. $extra_cond .= " AND post_status <> 'trash'";
  3322. }
  3323. // dont count auto drafts
  3324. $extra_cond .= " AND post_status <> 'auto-draft'";
  3325. $res = $wpdb->get_results("
  3326. SELECT language_code, COUNT(p.ID) AS c FROM {$wpdb->prefix}icl_translations t
  3327. JOIN {$wpdb->posts} p ON t.element_id=p.ID
  3328. JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active = 1
  3329. WHERE p.post_type='{$type}' AND t.element_type='post_{$type}' {$extra_cond}
  3330. GROUP BY language_code
  3331. ");
  3332. $langs['all'] = 0;
  3333. foreach($res as $r){
  3334. $langs[$r->language_code] = $r->c;
  3335. $langs['all'] += $r->c;
  3336. }
  3337. icl_cache_set($type.'s_per_language', $langs);
  3338. }
  3339. $active_languages[] = array('code'=>'all','display_name'=>__('All languages','sitepress'));
  3340. foreach($active_languages as $lang){
  3341. if($lang['code']== $this->this_lang){
  3342. $px = '<strong>';
  3343. $sx = ' <span class="count">('. @intval($langs[$lang['code']]) .')<\/span><\/strong>';
  3344. }elseif(!isset($langs[$lang['code']])){
  3345. $px = '<span>';
  3346. $sx = '<\/span>';
  3347. }else{
  3348. if($post_status){
  3349. $px = '<a href="?post_type='.$type.'&post_status='.$post_status.'&lang='.$lang['code'].'">';
  3350. }else{
  3351. $px = '<a href="?post_type='.$type.'&lang='.$lang['code'].'">';
  3352. }
  3353. $sx = '<\/a> <span class="count">('. intval($langs[$lang['code']]) .')<\/span>';
  3354. }
  3355. $as[] = $px . $lang['display_name'] . $sx;
  3356. }
  3357. $allas = join(' | ', $as);
  3358. if($type == 'page' && !$this->get_icl_translation_enabled()){
  3359. $prot_link = '<span class="button" style="padding:4px;margin-top:10px;"><img align="baseline" src="' . ICL_PLUGIN_URL .'/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="http://wpml.org/?page_id=3416">' .
  3360. __('How to translate', 'sitepress') . '<\/a>' . '<\/span>';
  3361. }else{
  3362. $prot_link = '';
  3363. }
  3364. ?>
  3365. <script type="text/javascript">
  3366. jQuery(".subsubsub").append('<br /><span id="icl_subsubsub"><?php echo $allas ?><\/span><br /><?php echo $prot_link ?>');
  3367. </script>
  3368. <?php
  3369. }
  3370. function exclude_other_language_pages2($arr){
  3371. if($this->get_current_language() != 'all'){
  3372. global $wpdb;
  3373. if(is_array($arr) && !empty($arr[0]->post_type)){
  3374. $post_type = $arr[0]->post_type;
  3375. }else{
  3376. $post_type = 'page';
  3377. }
  3378. $filtered_pages = array();
  3379. // grab list of pages NOT in the current language
  3380. $excl_pages = $wpdb->get_col($wpdb->prepare("
  3381. SELECT p.ID FROM {$wpdb->posts} p
  3382. JOIN {$wpdb->prefix}icl_translations t ON p.ID = t.element_id
  3383. WHERE t.element_type=%s AND p.post_type=%s AND t.language_code <> %s
  3384. ", 'post_' . $post_type, $post_type , $this->get_current_language()));
  3385. // exclude them from the result set
  3386. foreach($arr as $page){
  3387. if(!in_array($page->ID,$excl_pages)){
  3388. $filtered_pages[] = $page;
  3389. }
  3390. }
  3391. $arr = $filtered_pages;
  3392. }
  3393. return $arr;
  3394. }
  3395. function wp_dropdown_pages($output){
  3396. global $wpdb;
  3397. if(isset($_POST['lang_switch'])){
  3398. $post_id = $wpdb->escape($_POST['lang_switch']);
  3399. $lang = $wpdb->escape(strip_tags($_GET['lang']));
  3400. $parent = $wpdb->get_var($wpdb->prepare("SELECT post_parent FROM {$wpdb->posts} WHERE ID=%d", $post_id));
  3401. if($parent){
  3402. $trid = $wpdb->get_var("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id='{$parent}' AND element_type='post_page'");
  3403. $translated_parent_id = $wpdb->get_var("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid='{$trid}' AND element_type='post_page' AND language_code='{$lang}'");
  3404. if($translated_parent_id){
  3405. $output = str_replace('selected="selected"','',$output);
  3406. $output = str_replace('value="'.$translated_parent_id.'"','value="'.$translated_parent_id.'" selected="selected"',$output);
  3407. }
  3408. }
  3409. }elseif(isset($_GET['lang']) && isset($_GET['trid'])){
  3410. $lang = $wpdb->escape(strip_tags($_GET['lang']));
  3411. $trid = $wpdb->escape($_GET['trid']);
  3412. $post_type = isset($_GET['post_type']) ? $_GET['post_type'] : 'page';
  3413. $elements_id = $wpdb->get_col($wpdb->prepare(
  3414. "SELECT element_id FROM {$wpdb->prefix}icl_translations
  3415. WHERE trid=%d AND element_type=%s AND element_id IS NOT NULL", $trid, 'post_' . $post_type));
  3416. $translated_parent_id = 0;
  3417. foreach($elements_id as $element_id){
  3418. $parent = $wpdb->get_var($wpdb->prepare("SELECT post_parent FROM {$wpdb->posts} WHERE ID=%d", $element_id));
  3419. $trid = $wpdb->get_var($wpdb->prepare("
  3420. SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", $parent, 'post_' . $post_type
  3421. ));
  3422. $translated_parent_id = $wpdb->get_var($wpdb->prepare("
  3423. SELECT element_id FROM {$wpdb->prefix}icl_translations
  3424. WHERE trid=%d AND element_type=%s AND language_code=%s", $trid, 'post_' . $post_type, $lang
  3425. ));
  3426. if($translated_parent_id) break;
  3427. }
  3428. if($translated_parent_id){
  3429. $output = str_replace('selected="selected"','',$output);
  3430. $output = str_replace('value="'.$translated_parent_id.'"','value="'.$translated_parent_id.'" selected="selected"',$output);
  3431. }
  3432. }
  3433. if(!$output){
  3434. $output = '<select id="parent_id"><option value="">' . __('Main Page (no parent)','sitepress') . '</option></select>';
  3435. }
  3436. return $output;
  3437. }
  3438. function edit_term_form($term){
  3439. global $wpdb, $pagenow;
  3440. $element_id = isset($term->term_taxonomy_id)?$term->term_taxonomy_id:false;
  3441. $element_type = isset($_GET['taxonomy']) ? $wpdb->escape($_GET['taxonomy']) : 'post_tag';
  3442. $icl_element_type = 'tax_' . $element_type;
  3443. $default_language = $this->get_default_language();
  3444. if($element_id){
  3445. $res = $wpdb->get_row("SELECT trid, language_code, source_language_code
  3446. FROM {$wpdb->prefix}icl_translations WHERE element_id='{$element_id}' AND element_type='{$icl_element_type}'");
  3447. $trid = $res->trid;
  3448. if($trid){
  3449. $element_lang_code = $res->language_code;
  3450. }else{
  3451. $element_lang_code = $this->get_current_language();
  3452. $trid = $this->set_element_language_details($element_id, $icl_element_type, null, $element_lang_code);
  3453. }
  3454. }else{
  3455. $trid = isset($_GET['trid']) ? intval($_GET['trid']) : false;
  3456. $element_lang_code = isset($_GET['lang']) ? strip_tags($_GET['lang']) : $this->get_current_language();
  3457. }
  3458. if($trid){
  3459. $translations = $this->get_element_translations($trid, $icl_element_type);
  3460. }
  3461. $active_languages = $this->get_active_languages();
  3462. $selected_language = $element_lang_code?$element_lang_code:$default_language;
  3463. $source_language = isset($_GET['source_lang']) ? strip_tags($_GET['source_lang']) : false;
  3464. $untranslated_ids = $this->get_elements_without_translations($icl_element_type, $selected_language, $default_language);
  3465. include ICL_PLUGIN_PATH . '/menu/taxonomy-menu.php';
  3466. }
  3467. function wp_dropdown_cats_select_parent($html){
  3468. global $wpdb;
  3469. if(isset($_GET['trid'])){
  3470. $element_type = $taxonomy = isset($_GET['taxonomy']) ? $_GET['taxonomy'] : 'post_tag';
  3471. $icl_element_type = 'tax_' . $element_type;
  3472. $trid = intval($_GET['trid']);
  3473. $source_lang = isset($_GET['source_lang']) ? $_GET['source_lang'] : $this->get_default_language();
  3474. $parent = $wpdb->get_var("
  3475. SELECT parent
  3476. FROM {$wpdb->term_taxonomy} tt
  3477. JOIN {$wpdb->prefix}icl_translations tr ON tr.element_id=tt.term_taxonomy_id
  3478. AND tr.element_type='{$icl_element_type}' AND tt.taxonomy='{$taxonomy}'
  3479. WHERE trid='{$trid}' AND tr.language_code='{$source_lang}'
  3480. ");
  3481. if($parent){
  3482. $parent = icl_object_id($parent, $element_type);
  3483. $html = str_replace('value="'.$parent.'"', 'value="'.$parent.'" selected="selected"', $html);
  3484. }
  3485. }
  3486. return $html;
  3487. }
  3488. function add_language_selector_to_page($active_languages, $selected_language, $translations, $element_id, $type) {
  3489. ?>
  3490. <div id="icl_tax_menu" style="display:none">
  3491. <div id="dashboard-widgets" class="metabox-holder">
  3492. <div class="postbox-container" style="width: 99%;line-height:normal;">
  3493. <div id="icl_<?php echo $type ?>_lang" class="postbox" style="line-height:normal;">
  3494. <h3 class="hndle">
  3495. <span><?php echo __('Language', 'sitepress')?></span>
  3496. </h3>
  3497. <div class="inside" style="padding: 10px;">
  3498. <select name="icl_<?php echo $type ?>_language">
  3499. <?php
  3500. foreach($active_languages as $lang){
  3501. if ($lang['code'] == $selected_language) {
  3502. ?>
  3503. <option value="<?php echo $selected_language ?>" selected="selected"><?php echo $lang['display_name'] ?></option>
  3504. <?php
  3505. }
  3506. }
  3507. ?>
  3508. <?php foreach($active_languages as $lang):?>
  3509. <?php if($lang['code'] == $selected_language || (isset($translations[$lang['code']]->element_id) && $translations[$lang['code']]->element_id != $element_id)) continue ?>
  3510. <option value="<?php echo $lang['code'] ?>"<?php if($selected_language==$lang['code']): ?> selected="selected"<?php endif;?>><?php echo $lang['display_name'] ?></option>
  3511. <?php endforeach; ?>
  3512. </select>
  3513. <?php
  3514. }
  3515. function get_category_name($id) {
  3516. _deprecated_function( __FUNCTION__, '2.3.1', 'get_cat_name()' );
  3517. global $wpdb;
  3518. $term_id = $wpdb->get_var("SELECT term_id FROM {$wpdb->prefix}term_taxonomy WHERE term_taxonomy_id = {$id}");
  3519. if ($term_id) {
  3520. return $wpdb->get_var("SELECT name FROM {$wpdb->prefix}terms WHERE term_id = {$term_id}");
  3521. } else {
  3522. return null;
  3523. }
  3524. }
  3525. function add_translation_of_selector_to_page($trid,
  3526. $selected_language,
  3527. $default_language,
  3528. $source_language,
  3529. $untranslated_ids,
  3530. $element_id,
  3531. $type) {
  3532. global $wpdb;
  3533. ?>
  3534. <input type="hidden" name="icl_trid" value="<?php echo $trid ?>" />
  3535. <?php if($selected_language != $default_language && 'all' != $this->get_current_language()): ?>
  3536. <br /><br />
  3537. <?php echo __('This is a translation of', 'sitepress') ?><br />
  3538. <select name="icl_translation_of" id="icl_translation_of"<?php if((!isset($_GET['action']) || $_GET['action'] != 'edit') && $trid) echo " disabled"?>>
  3539. <?php if($source_language == null || $source_language == $default_language): ?>
  3540. <?php if($trid): ?>
  3541. <option value="none"><?php echo __('--None--', 'sitepress') ?></option>
  3542. <?php
  3543. //get source
  3544. $src_language_id = $wpdb->get_var("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid={$trid} AND language_code='{$default_language}'");
  3545. if(!$src_language_id) {
  3546. // select the first id found for this trid
  3547. $src_language_id = $wpdb->get_var("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid={$trid}");
  3548. }
  3549. if($src_language_id && $src_language_id != $element_id) {
  3550. $term_id = $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id=%d", $src_language_id));
  3551. $src_language_title = $wpdb->get_var($wpdb->prepare("SELECT name FROM {$wpdb->terms} WHERE term_id=%d", $term_id));
  3552. }
  3553. ?>
  3554. <?php if(!empty($src_language_title)): ?>
  3555. <option value="<?php echo $src_language_id ?>" selected="selected"><?php echo $src_language_title ?></option>
  3556. <?php endif; ?>
  3557. <?php else: ?>
  3558. <option value="none" selected="selected"><?php echo __('--None--', 'sitepress') ?></option>
  3559. <?php endif; ?>
  3560. <?php foreach($untranslated_ids as $translation_of_id):?>
  3561. <?php if ($translation_of_id != $src_language_id): ?>
  3562. <?php
  3563. $title = $wpdb->get_var($wpdb->prepare("SELECT name FROM {$wpdb->terms} WHERE term_id=%d",
  3564. $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id=%d", $translation_of_id))));
  3565. ?>
  3566. <?php if ($title): ?>
  3567. <option value="<?php echo $translation_of_id ?>"><?php echo $title ?></option>
  3568. <?php endif; ?>
  3569. <?php endif; ?>
  3570. <?php endforeach; ?>
  3571. <?php else: ?>
  3572. <?php if($trid): ?>
  3573. <?php
  3574. // add the source language
  3575. $src_language_id = $wpdb->get_var("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid={$trid} AND language_code='{$source_language}'");
  3576. if($src_language_id) {
  3577. $term_id = $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id=%d", $src_language_id));
  3578. $src_language_title = $wpdb->get_var($wpdb->prepare("SELECT name FROM {$wpdb->terms} WHERE term_id=%d", $term_id));
  3579. }
  3580. ?>
  3581. <?php if($src_language_title): ?>
  3582. <option value="<?php echo $src_language_id ?>" selected="selected"><?php echo $src_language_title ?></option>
  3583. <?php endif; ?>
  3584. <?php else: ?>
  3585. <option value="none" selected="selected"><?php echo __('--None--', 'sitepress') ?></option>
  3586. <?php endif; ?>
  3587. <?php endif; ?>
  3588. </select>
  3589. <?php endif; ?>
  3590. <?php
  3591. }
  3592. function add_translate_options($trid,
  3593. $active_languages,
  3594. $selected_language,
  3595. $translations,
  3596. $type) {
  3597. global $wpdb;
  3598. ?>
  3599. <?php if($trid && isset($_GET['action']) && $_GET['action'] == 'edit'): ?>
  3600. <div id="icl_translate_options">
  3601. <?php
  3602. // count number of translated and un-translated pages.
  3603. $translations_found = 0;
  3604. $untranslated_found = 0;
  3605. foreach($active_languages as $lang) {
  3606. if($selected_language==$lang['code']) continue;
  3607. if(isset($translations[$lang['code']]->element_id)) {
  3608. $translations_found += 1;
  3609. } else {
  3610. $untranslated_found += 1;
  3611. }
  3612. }
  3613. ?>
  3614. <?php if($untranslated_found > 0): ?>
  3615. <table cellspacing="1" class="icl_translations_table" style="min-width:200px;margin-top:10px;">
  3616. <thead>
  3617. <th colspan="2" style="padding:4px;background-color:#DFDFDF"><b><?php _e('Translate', 'sitepress'); ?></b></th>
  3618. </thead>
  3619. <tbody>
  3620. <?php foreach($active_languages as $lang): if($selected_language==$lang['code']) continue; ?>
  3621. <tr>
  3622. <?php if(!isset($translations[$lang['code']]->element_id)):?>
  3623. <td style="padding:4px;line-height:normal;"><?php echo $lang['display_name'] ?></td>
  3624. <?php
  3625. $taxonomy = $_GET['taxonomy'];
  3626. $post_type_q = isset($_GET['post_type']) ? '&amp;post_type=' . esc_html($_GET['post_type']) : '';
  3627. $add_link = admin_url("edit-tags.php?taxonomy=".esc_html($taxonomy)."&amp;trid=" . $trid . "&amp;lang=" . $lang['code'] . "&amp;source_lang=" . $selected_language . $post_type_q);
  3628. ?>
  3629. <td style="padding:4px;line-height:normal;"><a href="<?php echo $add_link ?>"><?php echo __('add','sitepress') ?></a></td>
  3630. <?php endif; ?>
  3631. </tr>
  3632. <?php endforeach; ?>
  3633. </tbody>
  3634. </table>
  3635. <?php endif; ?>
  3636. <?php if($translations_found > 0): ?>
  3637. <p style="clear:both;margin:5px 0 5px 0">
  3638. <b><?php _e('Translations', 'sitepress') ?></b>
  3639. (<a class="icl_toggle_show_translations" href="#" <?php if(empty($this->settings['show_translations_flag'])):?>style="display:none;"<?php endif;?>><?php _e('hide','sitepress')?></a><a class="icl_toggle_show_translations" href="#" <?php if(!empty($this->settings['show_translations_flag'])):?>style="display:none;"<?php endif;?>><?php _e('show','sitepress')?></a>)
  3640. <?php wp_nonce_field('toggle_show_translations_nonce', '_icl_nonce_tst') ?>
  3641. <table cellspacing="1" width="100%" id="icl_translations_table" style="<?php if(empty($this->settings['show_translations_flag'])):?>display:none;<?php endif;?>margin-left:0;">
  3642. <?php foreach($active_languages as $lang): if($selected_language==$lang['code']) continue; ?>
  3643. <tr>
  3644. <?php if(isset($translations[$lang['code']]->element_id)):?>
  3645. <td style="line-height:normal;"><?php echo $lang['display_name'] ?></td>
  3646. <?php
  3647. $taxonomy = $_GET['taxonomy'];
  3648. $post_type_q = isset($_GET['post_type']) ? '&amp;post_type=' . esc_html($_GET['post_type']) : '';
  3649. $edit_link = admin_url("edit-tags.php?taxonomy=".esc_html($taxonomy)."&amp;action=edit&amp;tag_ID=" . $translations[$lang['code']]->term_id . "&amp;lang=" . $lang['code'] . $post_type_q);
  3650. ?>
  3651. <td align="right" width="30%" style="line-height:normal;"><?php echo isset($translations[$lang['code']]->name)?'<a href="'.$edit_link.'" title="'.__('Edit','sitepress').'">'.$translations[$lang['code']]->name.'</a>':__('n/a','sitepress') ?></td>
  3652. <?php endif; ?>
  3653. </tr>
  3654. <?php endforeach; ?>
  3655. </table>
  3656. <?php endif; ?>
  3657. <br clear="all" style="line-height:1px;" />
  3658. </div>
  3659. <?php endif; ?>
  3660. <?php
  3661. }
  3662. function create_term($cat_id, $tt_id){
  3663. global $wpdb, $wp_taxonomies;
  3664. // case of ajax inline category creation
  3665. // ajax actions
  3666. foreach($wp_taxonomies as $ktx=>$tx){
  3667. $ajx_actions[] = 'add-' . $ktx;
  3668. }
  3669. if(isset($_POST['_ajax_nonce']) && in_array($_POST['action'], $ajx_actions)){
  3670. $referer = $_SERVER['HTTP_REFERER'];
  3671. $url_pieces = parse_url($referer);
  3672. @parse_str($url_pieces['query'], $qvars);
  3673. if(!empty($qvars['post'])){
  3674. $post_type = $wpdb->get_var($wpdb->prepare("SELECT post_type FROM {$wpdb->posts} WHERE ID = %d", $qvars['post']));
  3675. $lang_details = $this->get_element_language_details($qvars['post'],'post_' . $post_type);
  3676. $term_lang = $lang_details->language_code;
  3677. }else{
  3678. $term_lang = isset($qvars['lang']) ? $qvars['lang'] : $this->get_language_cookie();
  3679. }
  3680. }
  3681. $el_type = $wpdb->get_var("SELECT taxonomy FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id={$tt_id}");
  3682. if(!$this->is_translated_taxonomy($el_type)){
  3683. return;
  3684. };
  3685. $icl_el_type = 'tax_' . $el_type;
  3686. // case of adding a tag via post save
  3687. $post_action = isset($_POST['action']) ? $_POST['action'] : false;
  3688. if($post_action == 'editpost'){
  3689. $term_lang = $_POST['icl_post_language'];
  3690. }elseif($post_action == 'post-quickpress-publish'){
  3691. $term_lang = $this->get_default_language();
  3692. }elseif($post_action == 'inline-save-tax'){
  3693. $lang_details = $this->get_element_language_details($tt_id, $icl_el_type);
  3694. $term_lang = $lang_details->language_code;
  3695. }elseif($post_action == 'inline-save'){
  3696. $post_type = $wpdb->get_var("SELECT post_type FROM {$wpdb->posts} WHERE ID=" . $_POST['post_ID']);
  3697. $lang_details = $this->get_element_language_details($_POST['post_ID'], 'post_' . $post_type);
  3698. $term_lang = $lang_details->language_code;
  3699. }
  3700. // has trid only when it's a translation of another tag
  3701. $trid = isset($_POST['icl_trid']) && (isset($_POST['icl_'.$icl_el_type.'_language'])) ? $_POST['icl_trid']:null;
  3702. // see if we have a "translation of" setting.
  3703. $src_language = false;
  3704. if (isset($_POST['icl_translation_of']) && $_POST['icl_translation_of']) {
  3705. $src_term_id = $_POST['icl_translation_of'];
  3706. if ($src_term_id != 'none') {
  3707. $res = $wpdb->get_row("SELECT trid, language_code
  3708. FROM {$wpdb->prefix}icl_translations WHERE element_id={$src_term_id} AND element_type='{$icl_el_type}'");
  3709. $trid = $res->trid;
  3710. $src_language = $res->language_code;
  3711. } else {
  3712. $trid = null;
  3713. }
  3714. }
  3715. if(!isset($term_lang)){
  3716. $term_lang = isset($_POST['icl_'.$icl_el_type.'_language']) ? $_POST['icl_'.$icl_el_type.'_language'] : false;
  3717. }
  3718. if($post_action == 'inline-save-tax'){
  3719. $trid = $this->get_element_trid($tt_id, $icl_el_type);
  3720. }
  3721. $this->set_element_language_details($tt_id, $icl_el_type, $trid, $term_lang, $src_language);
  3722. // sync translations parent
  3723. if($this->settings['sync_taxonomy_parents'] && isset($_POST['parent']) && $term_lang == $this->get_default_language()){
  3724. $parent = intval($_POST['parent']);
  3725. $translations = $this->get_element_translations($trid, $icl_el_type);
  3726. foreach($translations as $lang=> $translation){
  3727. if($lang != $this->get_default_language()){
  3728. if($parent > 0){
  3729. $translated_parent = icl_object_id($parent, $el_type, false, $lang);
  3730. }
  3731. if($parent == 0 || $translated_parent != $parent){
  3732. $wpdb->update($wpdb->term_taxonomy, array('parent'=>$translated_parent), array('term_taxonomy_id'=>$translation->element_id));
  3733. }
  3734. }
  3735. }
  3736. delete_option($el_type . '_children');
  3737. }
  3738. }
  3739. function get_language_for_term($term_id, $el_type) {
  3740. global $wpdb;
  3741. $term_id = $wpdb->get_var("SELECT term_taxonomy_id FROM {$wpdb->prefix}term_taxonomy WHERE term_id = {$term_id}");
  3742. if ($term_id) {
  3743. return $wpdb->get_var("SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_id = {$term_id} AND element_type = '{$el_type}'");
  3744. } else {
  3745. return $this->get_default_language();
  3746. }
  3747. }
  3748. function pre_term_name($value, $taxonomy){
  3749. //allow adding terms with the same name in different languages
  3750. global $wpdb;
  3751. //check if term exists
  3752. $term_id = $wpdb->get_var("SELECT term_id FROM {$wpdb->terms} WHERE name='".$wpdb->escape($value)."'");
  3753. // translate to WPML notation
  3754. $taxonomy = 'tax_' . $taxonomy;
  3755. if(!empty($term_id)){
  3756. if(isset($_POST['icl_'.$taxonomy.'_language'])) {
  3757. // see if the term_id is for a different language
  3758. $this_lang = $_POST['icl_'.$taxonomy.'_language'];
  3759. if ($this_lang != $this->get_language_for_term($term_id, $taxonomy)) {
  3760. if ($this_lang != $this->get_default_language()){
  3761. $value .= ' @'.$_POST['icl_'.$taxonomy.'_language'];
  3762. }
  3763. }
  3764. }
  3765. }
  3766. return $value;
  3767. }
  3768. function pre_save_category(){
  3769. // allow adding categories with the same name in different languages
  3770. global $wpdb;
  3771. if(isset($_POST['action']) && $_POST['action']=='add-cat'){
  3772. if(category_exists($_POST['cat_name']) && isset($_POST['icl_category_language']) && $_POST['icl_category_language'] != $this->get_default_language()){
  3773. $_POST['cat_name'] .= ' @'.$_POST['icl_category_language'];
  3774. }
  3775. }
  3776. }
  3777. function delete_term($cat, $tt_id, $taxonomy){
  3778. global $wpdb;
  3779. $taxonomy = 'tax_' . $taxonomy;
  3780. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_translations WHERE element_type ='{$taxonomy}' AND element_id='{$tt_id}' LIMIT 1");
  3781. }
  3782. function get_term_filter($_term, $taxonomy){
  3783. // case of calling from get_category_parents
  3784. $db = debug_backtrace();
  3785. if(isset($db[5]['function']) && $db[5]['function'] == 'get_category_parents'){
  3786. $_term->name = $this->the_category_name_filter($_term->name);
  3787. }
  3788. return $_term;
  3789. }
  3790. function terms_language_filter(){
  3791. global $wpdb, $pagenow;
  3792. $taxonomy = isset($_GET['taxonomy']) ? $_GET['taxonomy'] : 'post_tag';
  3793. $icl_element_type = 'tax_' . $taxonomy;
  3794. $active_languages = $this->get_active_languages();
  3795. $res = $wpdb->get_results("
  3796. SELECT language_code, COUNT(tm.term_id) AS c FROM {$wpdb->prefix}icl_translations t
  3797. JOIN {$wpdb->term_taxonomy} tt ON t.element_id = tt.term_taxonomy_id
  3798. JOIN {$wpdb->terms} tm ON tt.term_id = tm.term_id
  3799. JOIN {$wpdb->prefix}icl_languages l ON t.language_code = l.code
  3800. WHERE t.element_type='{$icl_element_type}' AND tt.taxonomy='{$taxonomy}' AND l.active=1
  3801. GROUP BY language_code
  3802. ");
  3803. $langs = array('all'=>0);
  3804. foreach($res as $r){
  3805. $langs[$r->language_code] = $r->c;
  3806. $langs['all'] += $r->c;
  3807. }
  3808. $active_languages[] = array('code'=>'all','display_name'=>__('All languages','sitepress'));
  3809. foreach($active_languages as $lang){
  3810. if($lang['code']== $this->this_lang){
  3811. $px = '<strong>';
  3812. $sx = ' ('. @intval($langs[$lang['code']]) .')<\/strong>';
  3813. /*
  3814. }elseif(!isset($langs[$lang['code']])){
  3815. $px = '<span>';
  3816. $sx = '<\/span>';
  3817. */
  3818. }else{
  3819. $px = '<a href="?taxonomy='.$taxonomy.'&amp;lang='.$lang['code'];
  3820. $px .= isset($_GET['post_type']) ? '&amp;post_type=' . $_GET['post_type'] : '';
  3821. $px .= '">';
  3822. $sx = '<\/a> ('. @intval($langs[$lang['code']]) .')';
  3823. }
  3824. $as[] = $px . $lang['display_name'] . $sx;
  3825. }
  3826. $allas = join(' | ', $as);
  3827. ?>
  3828. <script type="text/javascript">
  3829. jQuery('table.widefat').before('<span id="icl_subsubsub"><?php echo $allas ?><\/span>');
  3830. </script>
  3831. <?php
  3832. }
  3833. function get_terms_args_filter($args){
  3834. // Unique cache domain for each language.
  3835. if(isset($args['cache_domain'])){
  3836. $args['cache_domain'] .= '_' . $this->get_current_language();
  3837. }
  3838. // special case for when term hierarchy is cached in wp_options
  3839. $dbbt = debug_backtrace();
  3840. if(isset($dbbt[4]) && $dbbt[4]['function'] == '_get_term_hierarchy'){
  3841. $args['_icl_show_all_langs'] = true;
  3842. }
  3843. return $args;
  3844. }
  3845. function exclude_other_terms($exclusions, $args){
  3846. // special case for when term hierarchy is cached in wp_options
  3847. if(isset($args['_icl_show_all_langs']) && $args['_icl_show_all_langs']) return $exclusions;
  3848. // get_terms doesn't seem to have a filter that can be used efficiently in order to filter the terms by language
  3849. // in addition the taxonomy name is not being passed to this filter we're using 'list_terms_exclusions'
  3850. // getting the taxonomy name from debug_backtrace
  3851. global $wpdb, $pagenow;
  3852. if(isset($_GET['taxonomy'])){
  3853. $taxonomy = $_GET['taxonomy'];
  3854. }elseif(isset($args['taxonomy'])){
  3855. $taxonomy = $args['taxonomy'];
  3856. }elseif(isset($_POST['action']) && $_POST['action']=='get-tagcloud'){
  3857. $taxonomy = $_POST['tax'];
  3858. }else{
  3859. if(in_array($pagenow, array('post-new.php','post.php', 'edit.php'))){
  3860. $dbt = debug_backtrace();
  3861. $taxonomy = $dbt[3]['args'][0];
  3862. }else{
  3863. $taxonomy = 'post_tag';
  3864. }
  3865. }
  3866. if(!$this->is_translated_taxonomy($taxonomy)){
  3867. return $exclusions;
  3868. }
  3869. $icl_element_type = 'tax_' . $taxonomy;
  3870. if(isset($_GET['lang']) && $_GET['lang']=='all'){
  3871. return $exclusions;
  3872. }
  3873. if(isset($_GET['tag_ID']) && $_GET['tag_ID']){
  3874. $element_lang_details = $this->get_element_language_details($wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", $_GET['tag_ID'], $taxonomy )), $icl_element_type);
  3875. $this_lang = $element_lang_details->language_code;
  3876. }elseif($this->this_lang != $this->get_default_language()){
  3877. $this_lang = $this->get_current_language();
  3878. }elseif(isset($_GET['post'])){
  3879. $icl_post_type = isset($_GET['post_type']) ? 'post_' . $_GET['post_type'] :
  3880. 'post_'. $wpdb->get_var($wpdb->prepare("SELECT post_type FROM {$wpdb->posts} WHERE ID = %d", $_GET['post']));
  3881. $element_lang_details = $this->get_element_language_details($_GET['post'],$icl_post_type);
  3882. $this_lang = $element_lang_details ? $element_lang_details->language_code : $this->get_default_language();
  3883. }elseif(isset($_POST['action']) && ($_POST['action']=='get-tagcloud' || $_POST['action']=='menu-quick-search')){
  3884. $urlparts = parse_url($_SERVER['HTTP_REFERER']);
  3885. @parse_str($urlparts['query'], $qvars);
  3886. $this_lang = isset($qvars['lang']) ? $qvars['lang'] : $this->get_default_language();
  3887. }else{
  3888. $this_lang = $this->get_default_language();
  3889. }
  3890. $exclude = $wpdb->get_col("
  3891. SELECT tt.term_taxonomy_id FROM {$wpdb->term_taxonomy} tt
  3892. LEFT JOIN {$wpdb->terms} tm ON tt.term_id = tm.term_id
  3893. LEFT JOIN {$wpdb->prefix}icl_translations t ON (tt.term_taxonomy_id = t.element_id OR t.element_id IS NULL)
  3894. WHERE tt.taxonomy='{$taxonomy}' AND t.element_type='{$icl_element_type}' AND t.language_code <> '{$this_lang}'
  3895. ");
  3896. $exclude[] = 0;
  3897. $exclusions .= ' AND tt.term_taxonomy_id NOT IN ('.join(',',$exclude).')';
  3898. return $exclusions;
  3899. }
  3900. function terms_clauses($clauses){
  3901. global $wpdb;
  3902. // special case for when term hierarchy is cached in wp_options
  3903. $dbbt = debug_backtrace();
  3904. if(isset($dbbt[4]) && $dbbt[4]['function'] == '_get_term_hierarchy'){
  3905. return $clauses;
  3906. }
  3907. $int = preg_match('#tt\.taxonomy IN \(([^\)]+)\)#', $clauses['where'], $matches);
  3908. $leftjoin = '';
  3909. if($int){
  3910. $exp = explode(',', $matches[1]);
  3911. foreach($exp as $k=>$v){
  3912. $tax = trim($v, ' \'');
  3913. if($this->is_translated_taxonomy($tax)){
  3914. $icl_taxs[] = 'tax_' . $tax;
  3915. }else{
  3916. $leftjoin = ' LEFT';
  3917. }
  3918. }
  3919. }else{
  3920. // taxonomy type not found
  3921. return $clauses;
  3922. }
  3923. if(empty($icl_taxs)) return $clauses;
  3924. $icl_taxs = "'" . join( "','" , $icl_taxs) . "'";
  3925. $lang = $this->get_current_language();
  3926. if($lang == 'all'){
  3927. $leftjoin = ' LEFT';
  3928. $where_lang = '';
  3929. }else{
  3930. $where_lang = " AND icl_t.language_code = '{$lang}'";
  3931. }
  3932. $clauses['join'] .= "{$leftjoin} JOIN {$wpdb->prefix}icl_translations icl_t ON icl_t.element_id = tt.term_taxonomy_id";
  3933. $clauses['where'] .= "{$where_lang} AND icl_t.element_type IN({$icl_taxs})";
  3934. //echo '<pre>' . print_r($clauses) . '</pre>';
  3935. return $clauses;
  3936. }
  3937. function set_wp_query(){
  3938. global $wp_query;
  3939. $this->wp_query = $wp_query;
  3940. }
  3941. // filter for WP home_url function
  3942. function home_url($url, $path, $orig_scheme, $blog_id){
  3943. // exception for get_page_num_link and language_negotiation_type = 3
  3944. if($this->settings['language_negotiation_type'] == 3){
  3945. $db = debug_backtrace();
  3946. if(!empty($db[6]) && $db[6]['function'] == 'get_pagenum_link') return $url;
  3947. }
  3948. // only apply this for home url - not for posts or page permalinks since this filter is called there too
  3949. if(did_action('template_redirect') && rtrim($url,'/') == rtrim(get_option('home'),'/')){
  3950. $url = $this->convert_url($url);
  3951. }
  3952. if($path == '/') $url = $this->convert_url($url);
  3953. return $url;
  3954. }
  3955. // converts WP generated url to language specific based on plugin settings
  3956. function convert_url($url, $code=null){
  3957. if(is_null($code)){
  3958. $code = $this->this_lang;
  3959. }
  3960. if($code && $code != $this->get_default_language()){
  3961. $abshome = preg_replace('@\?lang=' . $code . '@i','',get_option('home'));
  3962. switch($this->settings['language_negotiation_type']){
  3963. case '1':
  3964. if(0 === strpos($url, 'https://')){
  3965. $abshome = preg_replace('#^http://#', 'https://', $abshome);
  3966. }
  3967. if($abshome==$url) $url .= '/';
  3968. if (0 !== strpos($url, $abshome . '/' . $code . '/')) {
  3969. // only replace if it is there already
  3970. $url = str_replace($abshome, $abshome . '/' . $code, $url);
  3971. }
  3972. break;
  3973. case '2':
  3974. $url = str_replace($abshome, $this->settings['language_domains'][$code], $url);
  3975. break;
  3976. case '3':
  3977. default:
  3978. // remove any previous value.
  3979. if (strpos($url, '?lang=' . $code . '&') !== FALSE) {
  3980. $url = str_replace('?lang=' . $code . '&', '', $url);
  3981. } elseif (strpos($url, '?lang=' . $code . '/' ) !== FALSE) {
  3982. $url = str_replace('?lang=' . $code . '/', '', $url);
  3983. } elseif (strpos($url, '?lang=' . $code ) !== FALSE) {
  3984. $url = str_replace('?lang=' . $code, '', $url);
  3985. } elseif (strpos($url, '&lang=' . $code . '/') !== FALSE) {
  3986. $url = str_replace('&lang=' . $code . '/', '', $url);
  3987. } elseif (strpos($url, '&lang=' . $code ) !== FALSE) {
  3988. $url = str_replace('&lang=' . $code, '', $url);
  3989. }
  3990. if(false===strpos($url,'?')){
  3991. $url_glue = '?';
  3992. }else{
  3993. // special case post preview link
  3994. $db = debug_backtrace();
  3995. if(is_admin() && (@$db[6]['function'] == 'post_preview')){
  3996. $url_glue = '&';
  3997. }
  3998. elseif(isset($_POST['comment']) || defined('ICL_DOING_REDIRECT')){ // will be used for a redirect
  3999. $url_glue = '&';
  4000. }else{
  4001. $url_glue = '&amp;';
  4002. }
  4003. }
  4004. $url .= $url_glue . 'lang=' . $code;
  4005. }
  4006. }
  4007. return $url;
  4008. }
  4009. function language_url($code=null){
  4010. if(is_null($code)) $code = $this->this_lang;
  4011. $abshome = get_option('home');
  4012. if($this->settings['language_negotiation_type'] == 1 || $this->settings['language_negotiation_type'] == 2){
  4013. $url = trailingslashit($this->convert_url($abshome, $code));
  4014. }else{
  4015. $url = $this->convert_url($abshome, $code);
  4016. }
  4017. return $url;
  4018. }
  4019. function permalink_filter($p, $pid){
  4020. global $wpdb;
  4021. if(is_object($pid)){
  4022. $pid = $pid->ID;
  4023. }
  4024. $post_type = $wpdb->get_var("SELECT post_type FROM {$wpdb->posts} WHERE ID={$pid}");
  4025. if(!$this->is_translated_post_type($post_type)) return $p;
  4026. if($pid == (int)get_option('page_on_front')){
  4027. return $p;
  4028. }
  4029. $element_lang_details = $this->get_element_language_details($pid,'post_'.$post_type);
  4030. if(!empty($element_lang_details) && $element_lang_details->language_code && $this->get_default_language() != $element_lang_details->language_code){
  4031. $p = $this->convert_url($p, $element_lang_details->language_code);
  4032. }elseif(isset($_POST['action']) && $_POST['action']=='sample-permalink'){ // check whether this is an autosaved draft
  4033. $exp = explode('?', $_SERVER["HTTP_REFERER"]);
  4034. if(isset($exp[1])) parse_str($exp[1], $args);
  4035. if(isset($args['lang']) && $this->get_default_language() != $args['lang']){
  4036. $p = $this->convert_url($p, $args['lang']);
  4037. }
  4038. }
  4039. if(is_feed()){
  4040. $p = str_replace("&lang=", "&#038;lang=", $p);
  4041. }
  4042. return $p;
  4043. }
  4044. function category_permalink_filter($p, $cat_id){
  4045. global $wpdb;
  4046. if (isset($this->icl_term_taxonomy_cache)) {
  4047. $term_cat_id = $this->icl_term_taxonomy_cache->get('category_'.$cat_id);
  4048. } else {
  4049. $term_cat_id = null;
  4050. }
  4051. if (!$term_cat_id) {
  4052. $term_cat_id = $wpdb->get_var("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id={$cat_id} AND taxonomy='category'");
  4053. if (isset($this->icl_term_taxonomy_cache)) {
  4054. $this->icl_term_taxonomy_cache->set('category_'.$cat_id, $term_cat_id);
  4055. }
  4056. }
  4057. $cat_id = $term_cat_id;
  4058. $element_lang_details = $this->get_element_language_details($cat_id,'tax_category');
  4059. if($this->get_default_language() != $element_lang_details->language_code){
  4060. $p = $this->convert_url($p, $element_lang_details->language_code);
  4061. }
  4062. return $p;
  4063. }
  4064. function post_type_archive_link_filter($link, $post_type) {
  4065. if (isset($this->settings['custom_posts_sync_option'][$post_type])
  4066. && $this->settings['custom_posts_sync_option'][$post_type]) {
  4067. return $this->convert_url($link);
  4068. }
  4069. return $link;
  4070. }
  4071. function tax_permalink_filter($p, $tag){
  4072. global $wpdb;
  4073. if(is_object($tag)){
  4074. $tag_id = $tag->term_taxonomy_id;
  4075. $taxonomy = $tag->taxonomy;
  4076. }else{
  4077. $taxonomy = 'post_tag';
  4078. if (empty($tag_id)) {
  4079. $tag_id = $wpdb->get_var("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id={$tag} AND taxonomy='{$taxonomy}'");
  4080. if (isset($this->icl_term_taxonomy_cache)) {
  4081. $this->icl_term_taxonomy_cache->set($taxonomy . '_'.$tag, $tag_id);
  4082. }
  4083. }
  4084. }
  4085. $element_lang_details = $this->get_element_language_details($tag_id,'tax_' . $taxonomy);
  4086. if(!empty($element_lang_details) && $this->get_default_language() != $element_lang_details->language_code){
  4087. $p = $this->convert_url($p, $element_lang_details->language_code);
  4088. }
  4089. return $p;
  4090. }
  4091. function get_comment_link_filter($link){
  4092. // decode html characters since they are already encoded in the template for some reason
  4093. $link = html_entity_decode($link);
  4094. return $link;
  4095. }
  4096. function attachment_link_filter($link, $id) {
  4097. return $this->convert_url($link);
  4098. }
  4099. function get_ls_languages($template_args=array()){
  4100. global $wpdb, $post, $cat, $tag_id, $w_this_lang;
  4101. if(is_null($this->wp_query)) $this->set_wp_query();
  4102. // use original wp_query for this
  4103. // backup current $wp_query
  4104. global $wp_query;
  4105. $_wp_query_back = clone $wp_query;
  4106. $wp_query = clone $this->wp_query;
  4107. $w_active_languages = $this->get_active_languages();
  4108. $this_lang = $this->this_lang;
  4109. if($this_lang=='all'){
  4110. $w_this_lang = array(
  4111. 'code'=>'all',
  4112. 'english_name' => 'All languages',
  4113. 'display_name' => __('All languages', 'sitepress')
  4114. );
  4115. }else{
  4116. $w_this_lang = $this->get_language_details($this_lang);
  4117. }
  4118. if(isset($template_args['skip_missing'])){
  4119. //override default setting
  4120. $icl_lso_link_empty = !$template_args['skip_missing'];
  4121. }else{
  4122. $icl_lso_link_empty = $this->settings['icl_lso_link_empty'];
  4123. }
  4124. $user_agent = $_SERVER['HTTP_USER_AGENT'];
  4125. if(preg_match('#MSIE ([0-9]+)\.[0-9]#',$user_agent,$matches)){
  4126. $ie_ver = $matches[1];
  4127. }
  4128. if(is_attachment()){ // Exception for attachments. Not translated.
  4129. $translations[$this->get_current_language()] = (object) array(
  4130. 'translation_id' => 0,
  4131. 'language_code' => $this->get_default_language(),
  4132. 'element_id' => 0,
  4133. 'original' => 1,
  4134. 'post_title' => $this->wp_query->post->post_title,
  4135. 'post_status' => $this->wp_query->post->post_status
  4136. );
  4137. }elseif(is_singular() && !empty($wp_query->posts)){
  4138. $trid = $wpdb->get_var("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id='{$this->wp_query->post->ID}' AND element_type LIKE 'post\\_%'");
  4139. $translations = $this->get_element_translations($trid,'post_'.$wp_query->posts[0]->post_type);
  4140. }elseif(is_category() && !empty($wp_query->posts)){
  4141. $cat_id = $wpdb->get_var("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id={$cat} AND taxonomy='category'");
  4142. $trid = $wpdb->get_var("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id='{$cat_id}' AND element_type='tax_category'");
  4143. $skip_empty = true;
  4144. $translations = $this->get_element_translations($trid,'tax_category', $skip_empty);
  4145. }elseif(is_tag() && !empty($wp_query->posts)){
  4146. $tag_id = $wpdb->get_var("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id={$tag_id} AND taxonomy='post_tag'");
  4147. $trid = $wpdb->get_var("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id='{$tag_id}' AND element_type='tax_post_tag'");
  4148. $skip_empty = true;
  4149. $translations = $this->get_element_translations($trid,'tax_post_tag', $skip_empty);
  4150. }elseif(is_tax()){
  4151. $tax_id = $wpdb->get_var("SELECT term_taxonomy_id
  4152. FROM {$wpdb->term_taxonomy} WHERE term_id='".$wp_query->get_queried_object_id()."' AND taxonomy='".$wpdb->escape(get_query_var('taxonomy'))."'");
  4153. $trid = $this->get_element_trid($tax_id, 'tax_' . get_query_var('taxonomy'));
  4154. $skip_empty = true;
  4155. $translations = $this->get_element_translations($trid,'tax_' . get_query_var('taxonomy'), $skip_empty);
  4156. }elseif(is_archive() && !empty($wp_query->posts)){
  4157. $translations = array();
  4158. }elseif( 'page' == get_option('show_on_front') && (isset($this->wp_query->queried_object_id) && $this->wp_query->queried_object_id == get_option('page_on_front') || (isset($this->wp_query->queried_object_id) && $this->wp_query->queried_object_id == get_option('page_for_posts'))) ){
  4159. $trid = $wpdb->get_var("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id='{$this->wp_query->queried_object_id}' AND element_type='post_page'");
  4160. $translations = $this->get_element_translations($trid,'post_page');
  4161. }else{
  4162. $wp_query->is_singular = false;
  4163. $wp_query->is_archive = false;
  4164. $wp_query->is_category = false;
  4165. $wp_query->is_404 = true;
  4166. }
  4167. foreach($w_active_languages as $k=>$lang){
  4168. $skip_lang = false;
  4169. if(is_singular() || (!empty($this->wp_query->queried_object_id) && $this->wp_query->queried_object_id == get_option('page_for_posts'))){
  4170. $this_lang_tmp = $this->this_lang;
  4171. $this->this_lang = $lang['code'];
  4172. $lang_page_on_front = get_option('page_on_front');
  4173. $lang_page_for_posts = get_option('page_for_posts');
  4174. $this->this_lang = $this_lang_tmp;
  4175. if ( 'page' == get_option('show_on_front') && !empty($translations[$lang['code']]) && $translations[$lang['code']]->element_id == $lang_page_on_front ){
  4176. $lang['translated_url'] = $this->language_url($lang['code']);
  4177. }elseif('page' == get_option('show_on_front') && !empty($translations[$lang['code']]) && $translations[$lang['code']]->element_id && $translations[$lang['code']]->element_id == $lang_page_for_posts){
  4178. if($lang_page_for_posts){
  4179. $lang['translated_url'] = get_permalink($lang_page_for_posts);
  4180. }else{
  4181. $lang['translated_url'] = $this->language_url($lang['code']);
  4182. }
  4183. }else{
  4184. if(!empty($translations[$lang['code']]) && isset($translations[$lang['code']]->post_title)){
  4185. $lang['translated_url'] = get_permalink($translations[$lang['code']]->element_id);
  4186. $lang['missing'] = 0;
  4187. }else{
  4188. if($icl_lso_link_empty){
  4189. if(!empty($template_args['link_empty_to'])){
  4190. $lang['translated_url'] = str_replace('{%lang}', $lang['code'], $template_args['link_empty_to']);
  4191. }else{
  4192. $lang['translated_url'] = $this->language_url($lang['code']);
  4193. }
  4194. }else{
  4195. $skip_lang = true;
  4196. }
  4197. $lang['missing'] = 1;
  4198. }
  4199. }
  4200. }elseif(is_tax()){
  4201. if(isset($translations[$lang['code']])){
  4202. global $icl_adjust_id_url_filter_off; // force the category_link_adjust_id to not modify this
  4203. $icl_adjust_id_url_filter_off = true;
  4204. $lang['translated_url'] = get_term_link((int)$translations[$lang['code']]->term_id, get_query_var('taxonomy'));
  4205. $icl_adjust_id_url_filter_off = false; // restore default bahavior
  4206. $lang['missing'] = 0;
  4207. }else{
  4208. if($icl_lso_link_empty){
  4209. if(!empty($template_args['link_empty_to'])){
  4210. $lang['translated_url'] = str_replace('{%lang}', $lang['code'], $template_args['link_empty_to']);
  4211. }else{
  4212. $lang['translated_url'] = $this->language_url($lang['code']);
  4213. }
  4214. }else{
  4215. // dont skip the currrent language
  4216. if($this->get_current_language() != $lang['code']){
  4217. $skip_lang = true;
  4218. }
  4219. }
  4220. $lang['missing'] = 1;
  4221. }
  4222. }elseif(is_category()){
  4223. if(isset($translations[$lang['code']])){
  4224. global $icl_adjust_id_url_filter_off; // force the category_link_adjust_id to not modify this
  4225. $icl_adjust_id_url_filter_off = true;
  4226. $lang['translated_url'] = get_category_link($translations[$lang['code']]->term_id);
  4227. $icl_adjust_id_url_filter_off = false; // restore default bahavior
  4228. $lang['missing'] = 0;
  4229. }else{
  4230. if($icl_lso_link_empty){
  4231. if(!empty($template_args['link_empty_to'])){
  4232. $lang['translated_url'] = str_replace('{%lang}', $lang['code'], $template_args['link_empty_to']);
  4233. }else{
  4234. $lang['translated_url'] = $this->language_url($lang['code']);
  4235. }
  4236. }else{
  4237. // dont skip the currrent language
  4238. if($this->get_current_language() != $lang['code']){
  4239. $skip_lang = true;
  4240. }
  4241. }
  4242. $lang['missing'] = 1;
  4243. }
  4244. }elseif(is_tag()){
  4245. if(isset($translations[$lang['code']])){
  4246. global $icl_adjust_id_url_filter_off; // force the category_link_adjust_id to not modify this
  4247. $icl_adjust_id_url_filter_off = true;
  4248. $lang['translated_url'] = get_tag_link($translations[$lang['code']]->term_id);
  4249. $icl_adjust_id_url_filter_off = false; // restore default bahavior
  4250. $lang['missing'] = 0;
  4251. }else{
  4252. if($icl_lso_link_empty){
  4253. if(!empty($template_args['link_empty_to'])){
  4254. $lang['translated_url'] = str_replace('{%lang}', $lang['code'], $template_args['link_empty_to']);
  4255. }else{
  4256. $lang['translated_url'] = $this->language_url($lang['code']);
  4257. }
  4258. }else{
  4259. // dont skip the currrent language
  4260. if($this->get_current_language() != $lang['code']){
  4261. $skip_lang = true;
  4262. }
  4263. }
  4264. $lang['missing'] = 1;
  4265. }
  4266. }elseif(is_author()){
  4267. global $authordata, $wp_query;
  4268. if(empty($authordata)){
  4269. $authordata = get_userdata(get_query_var('author'));
  4270. }
  4271. $post_type = get_query_var('post_type') ? get_query_var('post_type') : 'post';
  4272. if($wpdb->get_var("SELECT COUNT(p.ID) FROM {$wpdb->posts} p
  4273. JOIN {$wpdb->prefix}icl_translations t ON p.ID=t.element_id AND t.element_type = 'post_{$post_type}'
  4274. WHERE p.post_author='{$authordata->ID}' AND post_type='{$post_type}' AND post_status='publish' AND language_code='{$lang['code']}'")
  4275. ){
  4276. remove_filter('home_url', array($this,'home_url'), 1, 4);
  4277. remove_filter('author_link', array($this,'author_link'));
  4278. $author_url = get_author_posts_url($authordata->ID);
  4279. add_filter('home_url', array($this,'home_url'), 1, 4);
  4280. add_filter('author_link', array($this,'author_link'));
  4281. $lang['translated_url'] = $this->convert_url($author_url, $lang['code']);
  4282. $lang['missing'] = 0;
  4283. }else{
  4284. if($icl_lso_link_empty){
  4285. if(!empty($template_args['link_empty_to'])){
  4286. $lang['translated_url'] = str_replace('{%lang}', $lang['code'], $template_args['link_empty_to']);
  4287. }else{
  4288. $lang['translated_url'] = $this->language_url($lang['code']);
  4289. }
  4290. }else{
  4291. // dont skip the currrent language
  4292. if($this->get_current_language() != $lang['code']){
  4293. $skip_lang = true;
  4294. }
  4295. }
  4296. $lang['missing'] = 1;
  4297. }
  4298. }elseif(is_archive() && !is_tag()){
  4299. global $icl_archive_url_filter_off;
  4300. $icl_archive_url_filter_off = true;
  4301. if($this->wp_query->is_year){
  4302. if(isset($this->wp_query->query_vars['m']) && !$this->wp_query->query_vars['year'] ){
  4303. $this->wp_query->query_vars['year'] = substr($this->wp_query->query_vars['m'], 0, 4);
  4304. }
  4305. $lang['translated_url'] = $this->archive_url(get_year_link( $this->wp_query->query_vars['year'] ), $lang['code']);
  4306. }elseif($this->wp_query->is_month){
  4307. if(isset($this->wp_query->query_vars['m']) && !$this->wp_query->query_vars['year'] ){
  4308. $this->wp_query->query_vars['year'] = substr($this->wp_query->query_vars['m'], 0, 4);
  4309. $this->wp_query->query_vars['monthnum'] = substr($this->wp_query->query_vars['m'], 4, 2);
  4310. }
  4311. $lang['translated_url'] = $this->archive_url(get_month_link( $this->wp_query->query_vars['year'], $this->wp_query->query_vars['monthnum'] ), $lang['code']);
  4312. }elseif($this->wp_query->is_day){
  4313. if(isset($this->wp_query->query_vars['m']) && !$this->wp_query->query_vars['year'] ){
  4314. $this->wp_query->query_vars['year'] = substr($this->wp_query->query_vars['m'], 0, 4);
  4315. $this->wp_query->query_vars['monthnum'] = substr($this->wp_query->query_vars['m'], 4, 2);
  4316. $this->wp_query->query_vars['day'] = substr($this->wp_query->query_vars['m'], 6, 2);
  4317. gmdate('Y', current_time('timestamp')); //force wp_timezone_override_offset to be called
  4318. }
  4319. $lang['translated_url'] = $this->archive_url(get_day_link( $this->wp_query->query_vars['year'], $this->wp_query->query_vars['monthnum'], $this->wp_query->query_vars['day'] ), $lang['code']);
  4320. } else if (isset($this->wp_query->query_vars['post_type'])) {
  4321. if (isset($this->settings['custom_posts_sync_option'][$this->wp_query->query_vars['post_type']])
  4322. && $this->settings['custom_posts_sync_option'][$this->wp_query->query_vars['post_type']]
  4323. && function_exists('get_post_type_archive_link')) {
  4324. remove_filter('post_type_archive_link', array($this,'post_type_archive_link_filter'), 10);
  4325. $lang['translated_url'] = $this->convert_url(get_post_type_archive_link($this->wp_query->query_vars['post_type']), $lang['code']);
  4326. } else {
  4327. $lang['translated_url'] = $this->language_url($lang['code']);
  4328. }
  4329. }
  4330. add_filter('post_type_archive_link', array($this,'post_type_archive_link_filter'), 10, 2);
  4331. $icl_archive_url_filter_off = false;
  4332. }elseif(is_search()){
  4333. $url_glue = strpos($this->language_url($lang['code']),'?')===false ? '?' : '&';
  4334. $lang['translated_url'] = $this->language_url($lang['code']) . $url_glue . 's=' . htmlspecialchars($_GET['s']);
  4335. }else{
  4336. global $icl_language_switcher_preview;
  4337. if($icl_lso_link_empty || is_home() || is_404()
  4338. || ('page' == get_option('show_on_front') && ($this->wp_query->queried_object_id == get_option('page_on_front')
  4339. || $this->wp_query->queried_object_id == get_option('page_for_posts')))
  4340. || $icl_language_switcher_preview){
  4341. $lang['translated_url'] = $this->language_url($lang['code']);
  4342. $skip_lang = false;
  4343. }else{
  4344. $skip_lang = true;
  4345. unset($w_active_languages[$k]);
  4346. }
  4347. }
  4348. if(!$skip_lang){
  4349. $w_active_languages[$k] = $lang;
  4350. }else{
  4351. unset($w_active_languages[$k]);
  4352. }
  4353. }
  4354. foreach($w_active_languages as $k=>$v){
  4355. $lang_code = $w_active_languages[$k]['language_code'] = $w_active_languages[$k]['code'];
  4356. unset($w_active_languages[$k]['code']);
  4357. $native_name = $this->get_display_language_name($lang_code, $lang_code);
  4358. if(!$native_name) $native_name = $w_active_languages[$k]['english_name'];
  4359. $w_active_languages[$k]['native_name'] = $native_name;
  4360. unset($w_active_languages[$k]['english_name']);
  4361. $translated_name = $this->get_display_language_name($lang_code, $this->get_current_language());
  4362. if(!$translated_name) $translated_name = $w_active_languages[$k]['english_name'];
  4363. $w_active_languages[$k]['translated_name'] = $translated_name;
  4364. unset($w_active_languages[$k]['display_name']);
  4365. $w_active_languages[$k]['url'] = $w_active_languages[$k]['translated_url'];
  4366. unset($w_active_languages[$k]['translated_url']);
  4367. $flag = $this->get_flag($lang_code);
  4368. if($flag->from_template){
  4369. $wp_upload_dir = wp_upload_dir();
  4370. $flag_url = $wp_upload_dir['baseurl'] . '/flags/' . $flag->flag;
  4371. }else{
  4372. $flag_url = ICL_PLUGIN_URL . '/res/flags/'.$flag->flag;
  4373. }
  4374. $w_active_languages[$k]['country_flag_url'] = $flag_url;
  4375. $w_active_languages[$k]['active'] = $this->get_current_language()==$lang_code?'1':0;;
  4376. }
  4377. // restore current $wp_query
  4378. $wp_query = clone $_wp_query_back;
  4379. unset($_wp_query_back);
  4380. $w_active_languages = apply_filters('icl_ls_languages', $w_active_languages);
  4381. $w_active_languages = $this->sort_ls_languages($w_active_languages, $template_args);
  4382. return $w_active_languages;
  4383. }
  4384. function sort_ls_languages($w_active_languages, $template_args) {
  4385. // sort languages according to parameters
  4386. if(isset($template_args['orderby'])){
  4387. if(isset($template_args['order'])){
  4388. $order = $template_args['order'];
  4389. }else{
  4390. $order = 'asc';
  4391. }
  4392. $comp = $order == 'asc' ? '>' : '<';
  4393. switch($template_args['orderby']){
  4394. case 'id':
  4395. uasort($w_active_languages, create_function('$a,$b','return $a[\'id\'] '.$comp.' $b[\'id\'];'));
  4396. break;
  4397. case 'code':
  4398. ksort($w_active_languages);
  4399. if($order == 'desc'){
  4400. $w_active_languages = array_reverse($w_active_languages);
  4401. }
  4402. break;
  4403. case 'name':
  4404. default:
  4405. uasort($w_active_languages, create_function('$a,$b','return $a[\'translated_name\'] '.$comp.' $b[\'translated_name\'];'));
  4406. }
  4407. }
  4408. return $w_active_languages;
  4409. }
  4410. function get_display_language_name($lang_code, $display_code) {
  4411. global $wpdb;
  4412. if (isset($this->icl_language_name_cache)) {
  4413. $translated_name = $this->icl_language_name_cache->get($lang_code.$display_code);
  4414. } else {
  4415. $translated_name = null;
  4416. }
  4417. if (!$translated_name) {
  4418. $translated_name = $wpdb->get_var("SELECT name FROM {$wpdb->prefix}icl_languages_translations WHERE language_code='{$lang_code}' AND display_language_code='{$display_code}'");
  4419. if (isset($this->icl_language_name_cache)) {
  4420. $this->icl_language_name_cache->set($lang_code.$display_code, $translated_name);
  4421. }
  4422. }
  4423. return $translated_name;
  4424. }
  4425. function get_flag($lang_code){
  4426. global $wpdb;
  4427. if (isset($this->icl_flag_cache)) {
  4428. $flag = $this->icl_flag_cache->get($lang_code);
  4429. } else {
  4430. $flag = null;
  4431. }
  4432. if (!$flag) {
  4433. $flag = $wpdb->get_row("SELECT flag, from_template FROM {$wpdb->prefix}icl_flags WHERE lang_code='{$lang_code}'");
  4434. if (isset($this->icl_flag_cache)) {
  4435. $this->icl_flag_cache->set($lang_code, $flag);
  4436. }
  4437. }
  4438. return $flag;
  4439. }
  4440. function get_flag_url($code){
  4441. $flag = $this->get_flag($code);
  4442. if($flag->from_template){
  4443. $flag_url = get_bloginfo('template_directory') . '/images/flags/'.$flag->flag;
  4444. }else{
  4445. $flag_url = ICL_PLUGIN_URL . '/res/flags/'.$flag->flag;
  4446. }
  4447. return $flag_url;
  4448. }
  4449. function language_selector(){
  4450. if(is_single()){
  4451. $post_type = get_query_var('post_type');
  4452. if(!$post_type) $post_type = 'post';
  4453. if(!$this->is_translated_post_type($post_type)){
  4454. return;
  4455. }
  4456. }elseif(is_tax()){
  4457. $tax = get_query_var('taxonomy');
  4458. if(!$this->is_translated_taxonomy($tax)){
  4459. return;
  4460. }
  4461. }
  4462. global $icl_language_switcher_preview;
  4463. if ($this->settings['icl_lang_sel_type'] == 'list' || $icl_language_switcher_preview){
  4464. global $icl_language_switcher;
  4465. $icl_language_switcher->widget_list();
  4466. if (!$icl_language_switcher_preview) return '';
  4467. }
  4468. $active_languages = $this->get_ls_languages();
  4469. foreach($active_languages as $k=>$al){
  4470. if($al['active']==1){
  4471. $main_language = $al;
  4472. unset($active_languages[$k]);
  4473. break;
  4474. }
  4475. }
  4476. include ICL_PLUGIN_PATH . '/menu/language-selector.php';
  4477. }
  4478. function have_icl_translator($source, $target){
  4479. // returns true if we have ICL translators for the language pair
  4480. if (isset($this->settings['icl_lang_status'])){
  4481. foreach($this->settings['icl_lang_status'] as $lang) {
  4482. if ($lang['from'] == $source && $lang['to'] == $target) {
  4483. return $lang['have_translators'];
  4484. }
  4485. }
  4486. }
  4487. return false;
  4488. }
  4489. function get_default_categories(){
  4490. $default_categories_all = $this->settings['default_categories'];
  4491. foreach($this->active_languages as $l) $alcodes[] = $l['code'];
  4492. foreach($default_categories_all as $c=>$v){
  4493. if(in_array($c, $alcodes)){
  4494. $default_categories[$c] = $v;
  4495. }
  4496. }
  4497. return $default_categories;
  4498. }
  4499. function set_default_categories($def_cat){
  4500. $this->settings['default_categories'] = $def_cat;
  4501. $this->save_settings();
  4502. }
  4503. function pre_option_default_category($setting){
  4504. global $wpdb;
  4505. if(isset($_POST['icl_post_language']) && $_POST['icl_post_language'] || (isset($_GET['lang']) && $_GET['lang']!='all')){
  4506. $lang = isset($_POST['icl_post_language']) && $_POST['icl_post_language'] ? $_POST['icl_post_language'] : $_GET['lang'];
  4507. $ttid = @intval($this->settings['default_categories'][$lang]);
  4508. return $tid = $wpdb->get_var("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id={$ttid} AND taxonomy='category'");
  4509. }
  4510. return false;
  4511. }
  4512. function update_option_default_category($oldvalue, $newvalue){
  4513. global $wpdb;
  4514. $newvalue = $wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE taxonomy='category' AND term_id=%d", $newvalue));
  4515. $translations = $this->get_element_translations($this->get_element_trid($newvalue, 'tax_category'));
  4516. if(!empty($translations)){
  4517. foreach($translations as $t){
  4518. $icl_settings['default_categories'][$t->language_code] = $t->element_id;
  4519. }
  4520. $this->save_settings($icl_settings);
  4521. }
  4522. }
  4523. function the_category_name_filter($name){
  4524. if(is_array($name)){
  4525. foreach($name as $k=>$v){
  4526. $name[$k] = $this->the_category_name_filter($v);
  4527. }
  4528. return $name;
  4529. }
  4530. if(false === strpos($name, '@')) return $name;
  4531. if(false !== strpos($name, '<a')){
  4532. $int = preg_match_all('|<a([^>]+)>([^<]+)</a>|i',$name,$matches);
  4533. if($int && count($matches[0]) > 1){
  4534. $originals = $filtered = array();
  4535. foreach($matches[0] as $m){
  4536. $originals[] = $m;
  4537. $filtered[] = $this->the_category_name_filter($m);
  4538. }
  4539. $name = str_replace($originals, $filtered, $name);
  4540. }else{
  4541. $name_sh = strip_tags($name);
  4542. $exp = explode('@', $name_sh);
  4543. $name = str_replace($name_sh, trim($exp[0]),$name);
  4544. }
  4545. }else{
  4546. $name = preg_replace('#(.*) @(.*)#i','$1',$name);
  4547. }
  4548. return $name;
  4549. }
  4550. function get_terms_filter($terms){
  4551. foreach($terms as $k=>$v){
  4552. if(isset($terms[$k]->name)) $terms[$k]->name = $this->the_category_name_filter($terms[$k]->name);
  4553. }
  4554. return $terms;
  4555. }
  4556. function get_the_terms_filter($terms, $id, $taxonomy ) {
  4557. if (!empty($this->settings['taxonomies_sync_option'][$taxonomy])) {
  4558. $terms = $this->get_terms_filter($terms);
  4559. }
  4560. return $terms;
  4561. }
  4562. function get_term_adjust_id($term){
  4563. global $icl_adjust_id_url_filter_off, $wpdb;
  4564. if($icl_adjust_id_url_filter_off) return $term; // special cases when we need the category in a different language
  4565. // exception: don't filter when called from get_permalink. When category parents are determined
  4566. $db = debug_backtrace();
  4567. if(isset($db[5]['function']) && $db[5]['function'] == 'get_category_parents' || isset($db[6]['function']) && $db[6]['function'] == 'get_permalink'){
  4568. return $term;
  4569. }
  4570. $translated_id = icl_object_id($term->term_id, $term->taxonomy, true);
  4571. if($translated_id != $term->term_id){
  4572. //$translated_id = $wpdb->get_var("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id='{$translated_id}'");
  4573. remove_filter('get_term', array($this,'get_term_adjust_id'), 1);
  4574. $t_term = get_term($translated_id, $term->taxonomy);
  4575. if(!is_wp_error($t_term)){
  4576. $term = $t_term;
  4577. }
  4578. add_filter('get_term', array($this,'get_term_adjust_id'), 1, 1);
  4579. }
  4580. return $term;
  4581. }
  4582. function get_term_by_name_and_lang(&$name, $type, $lang) {
  4583. global $wpdb;
  4584. $the_term = get_term_by('name', $name, $type);
  4585. if ($the_term) {
  4586. $term_lang = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM {$wpdb->prefix}icl_translations
  4587. WHERE element_id=%d AND element_type=%s", $the_term->term_taxonomy_id, 'tax_' . $type));
  4588. if ($term_lang != $lang) {
  4589. // term is in the wrong language
  4590. // Add lang code to term name.
  4591. $name .= ' @' . $lang;
  4592. $the_term = get_term_by('name', $name, $type);
  4593. }
  4594. }
  4595. return $the_term;
  4596. }
  4597. function set_term_translation($original_term, $translation_id, $type, $lang, $original_lang) {
  4598. global $wpdb;
  4599. if ($original_term) {
  4600. $trid = $this->get_element_trid($original_term->term_taxonomy_id,'tax_' . $type);
  4601. $this->set_element_language_details($translation_id, 'tax_' . $type, $trid, $lang, $original_lang);
  4602. } else {
  4603. // Original has been deleled.
  4604. // we need to set the language of the new term.
  4605. $wpdb->update($wpdb->prefix.'icl_translations',
  4606. array('language_code'=>$lang),
  4607. array('element_type'=>'tax_' . $type, 'element_id'=>$translation_id));
  4608. }
  4609. }
  4610. function wp_list_pages_adjust_ids($out, $args){
  4611. static $__run_once = false; // only run for calls that have 'include' as an argument. ant only run once.
  4612. if($args['include'] && !$__run_once && $this->get_current_language() != $this->get_default_language()){
  4613. $__run_once = true;
  4614. $include = array_map('trim', explode(',', $args['include']));
  4615. $tr_include = array();
  4616. foreach($include as $i){
  4617. $t = icl_object_id($i, 'page',true);
  4618. if($t){
  4619. $tr_include[] = $t;
  4620. }
  4621. }
  4622. $args['include'] = join(',',$tr_include);
  4623. $out = wp_list_pages($args);
  4624. }
  4625. return $out;
  4626. }
  4627. function get_terms_adjust_ids($terms, $taxonomies, $args){
  4628. static $__run_once = false; // only run for calls that have 'include' as an argument. ant only run once.
  4629. if($args['include'] && !$__run_once && $this->get_current_language() != $this->get_default_language()){
  4630. $__run_once = true;
  4631. if(is_array($args['include'])){
  4632. $include = $args['include'];
  4633. }else{
  4634. $include = array_map('trim', explode(',', $args['include']));
  4635. }
  4636. $tr_include = array();
  4637. foreach($include as $i){
  4638. $t = icl_object_id($i, $taxonomies[0],true);
  4639. if($t){
  4640. $tr_include[] = $t;
  4641. }
  4642. }
  4643. $args['include'] = join(',',$tr_include);
  4644. $terms = get_terms($taxonomies, $args);
  4645. }
  4646. return $terms;
  4647. }
  4648. function get_pages_adjust_ids($pages, $args){
  4649. static $__run_once = false; // only run for calls that have 'include' as an argument. ant only run once.
  4650. if(!$__run_once && $this->get_current_language() != $this->get_default_language()){
  4651. $__run_once = true;
  4652. $args_updated = false;
  4653. if($args['include']){
  4654. $include = array_map('trim', explode(',', $args['include']));
  4655. $tr_include = array();
  4656. foreach($include as $i){
  4657. $t = icl_object_id($i, 'page', true);
  4658. if($t){
  4659. $tr_include[] = $t;
  4660. }
  4661. }
  4662. $args['include'] = join(',',$tr_include);
  4663. $args_updated = true;
  4664. }
  4665. if($args['child_of']){
  4666. $args['child_of'] = icl_object_id($args['child_of'], 'page', true);
  4667. $args_updated = true;
  4668. }
  4669. if($args_updated){
  4670. $pages = get_pages($args);
  4671. }
  4672. }
  4673. return $pages;
  4674. }
  4675. function category_link_adjust_id($catlink, $cat_id){
  4676. global $icl_adjust_id_url_filter_off, $wpdb;
  4677. if($icl_adjust_id_url_filter_off) return $catlink; // special cases when we need the categiry in a different language
  4678. $translated_id = icl_object_id($cat_id, 'category', true);
  4679. if($translated_id && $translated_id != $cat_id){
  4680. $translated_id = $wpdb->get_var("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id='{$translated_id}'");
  4681. remove_filter('category_link', array($this,'category_link_adjust_id'), 1);
  4682. $catlink = get_category_link($translated_id, 'category');
  4683. add_filter('category_link', array($this,'category_link_adjust_id'), 1, 2);
  4684. }
  4685. return $catlink;
  4686. }
  4687. // adjacent posts links
  4688. function get_adjacent_post_join($join){
  4689. global $wpdb;
  4690. $post_type = get_query_var('post_type');
  4691. if(!$post_type) $post_type = 'post';
  4692. if($this->is_translated_post_type($post_type)){
  4693. $join .= " JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type = 'post_{$post_type}'";
  4694. }
  4695. return $join;
  4696. }
  4697. function get_adjacent_post_where($where){
  4698. global $wpdb;
  4699. $post_type = get_query_var('post_type');
  4700. if(!$post_type) $post_type = 'post';
  4701. if($this->is_translated_post_type($post_type)){
  4702. $where .= " AND language_code = '{$wpdb->escape($this->this_lang)}'";
  4703. }
  4704. return $where;
  4705. }
  4706. // feeds links
  4707. function feed_link($out){
  4708. return $this->convert_url($out);
  4709. }
  4710. // commenting links
  4711. function post_comments_feed_link($out){
  4712. if($this->settings['language_negotiation_type']==3){
  4713. $out = preg_replace('@(\?|&)lang=([^/]+)/feed/@i','feed/$1lang=$2',$out);
  4714. }
  4715. return $out;
  4716. //return $this->convert_url($out);
  4717. }
  4718. function trackback_url($out){
  4719. return $this->convert_url($out);
  4720. }
  4721. function user_trailingslashit($string, $type_of_url){
  4722. // fixes comment link for when the comments list pagination is enabled
  4723. if($type_of_url=='comment'){
  4724. $string = preg_replace('@(.*)/\?lang=([a-z-]+)/(.*)@is','$1/$3?lang=$2', $string);
  4725. }
  4726. return $string;
  4727. }
  4728. // archives links
  4729. function getarchives_join($join){
  4730. global $wpdb;
  4731. $join .= " JOIN {$wpdb->prefix}icl_translations t ON t.element_id = {$wpdb->posts}.ID AND t.element_type='post_post'";
  4732. return $join;
  4733. }
  4734. function getarchives_where($where){
  4735. global $wpdb;
  4736. $where .= " AND language_code = '{$wpdb->escape($this->this_lang)}'";
  4737. return $where;
  4738. }
  4739. function archives_link($out){
  4740. global $icl_archive_url_filter_off;
  4741. if(!$icl_archive_url_filter_off){
  4742. $out = $this->archive_url($out, $this->this_lang);
  4743. }
  4744. $icl_archive_url_filter_off = false;
  4745. return $out;
  4746. }
  4747. function archive_url($url, $lang){
  4748. $url = $this->convert_url($url, $lang);
  4749. return $url;
  4750. }
  4751. function author_link($url){
  4752. $url = $this->convert_url($url);
  4753. return preg_replace('#^http://(.+)//(.+)$#','http://$1/$2', $url);
  4754. }
  4755. // Navigation
  4756. //function get_pagenum_link_filter($url){
  4757. // fix pagenum links for when using the language as a parameter
  4758. // remove language query string appended by WP
  4759. // WPML adds the language parameter after the url is built
  4760. // $url = str_replace(get_option('home') . '?lang=' . $this->get_current_language(), get_option('home'), $url);
  4761. // return $url;
  4762. //}
  4763. function pre_option_home(){
  4764. if(!defined('TEMPLATEPATH')) return false;
  4765. $dbbt = debug_backtrace();
  4766. static $inc_methods = array('include','include_once','require','require_once');
  4767. if(isset($dbbt['4']) && $dbbt['4']['function']=='get_bloginfo' && isset($dbbt['5']) && $dbbt['5']['function']=='bloginfo'){ // case of bloginfo
  4768. $is_template_file = false !== strpos($dbbt[5]['file'], realpath(TEMPLATEPATH));
  4769. $is_direct_call = in_array($dbbt[6]['function'], $inc_methods) || (false !== strpos($dbbt[6]['file'], realpath(TEMPLATEPATH)));
  4770. }elseif(isset($dbbt['4']) && $dbbt['4']['function']=='get_bloginfo'){ // case of get_bloginfo
  4771. $is_template_file = false !== strpos($dbbt[4]['file'], realpath(TEMPLATEPATH));
  4772. $is_direct_call = in_array($dbbt[5]['function'], $inc_methods) || (false !== strpos($dbbt[5]['file'], realpath(TEMPLATEPATH)));
  4773. }elseif(isset($dbbt['4']) && $dbbt['4']['function']=='get_settings'){ // case of get_settings
  4774. $is_template_file = false !== strpos($dbbt[4]['file'], realpath(TEMPLATEPATH));
  4775. $is_direct_call = in_array($dbbt[5]['function'], $inc_methods) || (false !== strpos($dbbt[5]['file'], realpath(TEMPLATEPATH)));
  4776. }else{ // case of get_option
  4777. $is_template_file = isset($dbbt[3]['file']) && (false !== strpos($dbbt[3]['file'], realpath(TEMPLATEPATH)));
  4778. $is_direct_call = isset($dbbt['4']) && in_array($dbbt[4]['function'], $inc_methods) || (isset($dbbt[4]['file']) && false !== strpos($dbbt[4]['file'], realpath(TEMPLATEPATH)));
  4779. }
  4780. //if($dbbt[3]['file'] == @realpath(TEMPLATEPATH . '/header.php')){
  4781. if($is_template_file && $is_direct_call){
  4782. $ret = $this->language_url($this->this_lang);
  4783. }else{
  4784. $ret = false;
  4785. }
  4786. return $ret;
  4787. }
  4788. function query_vars($public_query_vars){
  4789. $public_query_vars[] = 'lang';
  4790. global $wp_query;
  4791. $wp_query->query_vars['lang'] = $this->this_lang;
  4792. return $public_query_vars;
  4793. }
  4794. function parse_query($q){
  4795. global $wp_query, $wpdb;
  4796. //if($q == $wp_query) return; // not touching the WP query
  4797. if(is_admin()) return;
  4798. if($this->get_current_language() != $this->get_default_language()) {
  4799. $cat_array = array();
  4800. // cat
  4801. if(isset($q->query_vars['cat']) && !empty($q->query_vars['cat'])){
  4802. $cat_array = array_map('intval', array_map('trim', explode(',', $q->query_vars['cat'])));
  4803. }
  4804. // category_name
  4805. if(isset($q->query_vars['category_name']) && !empty($q->query_vars['category_name'])){
  4806. $cat = get_term_by( 'slug', preg_replace('#((.*)/)#','',$q->query_vars['category_name']), 'category' );
  4807. if(!$cat){
  4808. $cat = get_term_by( 'name', $q->query_vars['category_name'], 'category' );
  4809. }
  4810. if($cat_id = $cat->term_id){
  4811. $cat_array = array($cat_id);
  4812. }else{
  4813. $q->query_vars['p'] = -1;
  4814. }
  4815. }
  4816. // category_and
  4817. if(isset($q->query_vars['category__and']) && !empty($q->query_vars['category__and'])){
  4818. $cat_array = $q->query_vars['category__and'];
  4819. }
  4820. // category_in
  4821. if(isset($q->query_vars['category__in']) && !empty($q->query_vars['category__in'])){
  4822. $cat_array = array_unique(array_merge($cat_array, array_map('intval', $q->query_vars['category__in'])));
  4823. }
  4824. // category__not_in
  4825. if(isset($q->query_vars['category__not_in']) && !empty($q->query_vars['category__not_in'])){
  4826. $__cats = array_map(create_function('$a', 'return -1*intval($a);'), $q->query_vars['category__not_in']);
  4827. $cat_array = array_unique(array_merge($cat_array, $__cats));
  4828. }
  4829. if(!empty($cat_array)){
  4830. $translated_ids = array();
  4831. foreach($cat_array as $c){
  4832. if(intval($c) < 0){
  4833. $sign = -1;
  4834. }else{
  4835. $sign = 1;
  4836. }
  4837. $translated_ids[] = $sign * intval(icl_object_id(abs($c), 'category', true));
  4838. }
  4839. //cat
  4840. if(isset($q->query_vars['cat']) && !empty($q->query_vars['cat'])){
  4841. $q->query_vars['cat'] = join(',', $translated_ids);
  4842. }
  4843. // category_name
  4844. if(isset($q->query_vars['category_name']) && !empty($q->query_vars['category_name'])){
  4845. $_ctmp = get_term_by('id', $translated_ids[0], 'category');
  4846. $q->query_vars['category_name'] = $_ctmp->slug;
  4847. }
  4848. // category__and
  4849. if(isset($q->query_vars['category__and']) && !empty($q->query_vars['category__and'])){
  4850. $q->query_vars['category__and'] = $translated_ids;
  4851. }
  4852. // category__in
  4853. if(isset($q->query_vars['category__in']) && !empty($q->query_vars['category__in'])){
  4854. $q->query_vars['category__in'] = array_filter($translated_ids, create_function('$a', 'return $a>0;'));
  4855. }
  4856. // category__not_in
  4857. if(isset($q->query_vars['category__not_in']) && !empty($q->query_vars['category__not_in'])){
  4858. $q->query_vars['category__not_in'] = array_filter($translated_ids, create_function('$a', 'return $a<0;'));
  4859. }
  4860. }
  4861. // TAGS
  4862. $tag_array = array();
  4863. // tag
  4864. if(isset($q->query_vars['tag']) && !empty($q->query_vars['tag'])){
  4865. if(false !== strpos($q->query_vars['tag'],' ')){
  4866. $tag_glue = '+';
  4867. $exp = explode(' ', $q->query_vars['tag']);
  4868. }else{
  4869. $tag_glue = ',';
  4870. $exp = explode(',', $q->query_vars['tag']);
  4871. }
  4872. $tag_ids = array();
  4873. foreach($exp as $e){
  4874. $tag_array[] = $wpdb->get_var($wpdb->prepare( "SELECT x.term_id FROM $wpdb->terms t
  4875. JOIN $wpdb->term_taxonomy x ON t.term_id=x.term_id WHERE x.taxonomy='post_tag' AND t.slug='%s'", $wpdb->escape($e)));
  4876. }
  4877. $_tmp = array_unique($tag_array);
  4878. if(count($_tmp) == 1 && empty($_tmp[0])){
  4879. $tag_array = array();
  4880. }
  4881. }
  4882. // tag_id
  4883. if(isset($q->query_vars['tag_id']) && !empty($q->query_vars['tag_id'])){
  4884. $tag_array = array_map('trim', explode(',', $q->query_vars['tag_id']));
  4885. }
  4886. // tag__and
  4887. if(isset($q->query_vars['tag__and']) && !empty($q->query_vars['tag__and'])){
  4888. $tag_array = $q->query_vars['tag__and'];
  4889. }
  4890. // tag__in
  4891. if(isset($q->query_vars['tag__in']) && !empty($q->query_vars['tag__in'])){
  4892. $tag_array = $q->query_vars['tag__in'];
  4893. }
  4894. // tag__not_in
  4895. if(isset($q->query_vars['tag__not_in']) && !empty($q->query_vars['tag__not_in'])){
  4896. $tag_array = $q->query_vars['tag__not_in'];
  4897. }
  4898. // tag_slug__in
  4899. if(isset($q->query_vars['tag_slug__in']) && !empty($q->query_vars['tag_slug__in'])){
  4900. foreach($q->query_vars['tag_slug__in'] as $t){
  4901. $tag_array[] = $wpdb->get_var($wpdb->prepare( "SELECT x.term_id FROM $wpdb->terms t
  4902. JOIN $wpdb->term_taxonomy x ON t.term_id=x.term_id WHERE x.taxonomy='post_tag' AND t.slug='%s'", $wpdb->escape($t)));
  4903. }
  4904. }
  4905. // tag_slug__and
  4906. if(isset($q->query_vars['tag_slug__and']) && !empty($q->query_vars['tag_slug__and'])){
  4907. foreach($q->query_vars['tag_slug__and'] as $t){
  4908. $tag_array[] = $wpdb->get_var($wpdb->prepare( "SELECT x.term_id FROM $wpdb->terms t
  4909. JOIN $wpdb->term_taxonomy x ON t.term_id=x.term_id WHERE x.taxonomy='post_tag' AND t.slug='%s'", $wpdb->escape($t)));
  4910. }
  4911. }
  4912. if(!empty($tag_array)){
  4913. $translated_ids = array();
  4914. foreach($tag_array as $c){
  4915. if(intval($c) < 0){
  4916. $sign = -1;
  4917. }else{
  4918. $sign = 1;
  4919. }
  4920. $_tid = intval(icl_object_id(abs($c), 'post_tag', true));
  4921. $translated_ids[] = $sign * $_tid;
  4922. }
  4923. }
  4924. //tag
  4925. if(isset($q->query_vars['tag']) && !empty($q->query_vars['tag'])){
  4926. if(isset($translated_ids)){
  4927. $slugs = $wpdb->get_col("SELECT slug FROM $wpdb->terms WHERE term_id IN (".join(',', $translated_ids).")");
  4928. $q->query_vars['tag'] = join($tag_glue, $slugs);
  4929. }
  4930. }
  4931. //tag_id
  4932. if(isset($q->query_vars['tag_id']) && !empty($q->query_vars['tag_id'])){
  4933. $q->query_vars['tag_id'] = join(',', $translated_ids);
  4934. }
  4935. // tag__and
  4936. if(isset($q->query_vars['tag__and']) && !empty($q->query_vars['tag__and'])){
  4937. $q->query_vars['tag__and'] = $translated_ids;
  4938. }
  4939. // tag__in
  4940. if(isset($q->query_vars['tag__in']) && !empty($q->query_vars['tag__in'])){
  4941. $q->query_vars['tag__in'] = $translated_ids;
  4942. }
  4943. // tag__not_in
  4944. if(isset($q->query_vars['tag__not_in']) && !empty($q->query_vars['tag__not_in'])){
  4945. $q->query_vars['tag__not_in'] = array_map('abs', $translated_ids);
  4946. }
  4947. // tag_slug__in
  4948. if(isset($q->query_vars['tag_slug__in']) && !empty($q->query_vars['tag_slug__in'])){
  4949. $q->query_vars['tag_slug__in'] = $wpdb->get_col("SELECT slug FROM $wpdb->terms WHERE term_id IN (".join(',', $translated_ids).")");
  4950. }
  4951. // tag_slug__and
  4952. if(isset($q->query_vars['tag_slug__and']) && !empty($q->query_vars['tag_slug__and'])){
  4953. $q->query_vars['tag_slug__and'] = $wpdb->get_col("SELECT slug FROM $wpdb->terms WHERE term_id IN (".join(',', $translated_ids).")");
  4954. }
  4955. // POST & PAGES
  4956. $post_type = isset($q->query_vars['post_type']) ? $q->query_vars['post_type'] : 'post';
  4957. // page_id
  4958. if(isset($q->query_vars['page_id']) && !empty($q->query_vars['page_id'])){
  4959. $q->query_vars['page_id'] = icl_object_id($q->query_vars['page_id'], 'page', true);
  4960. $q->query = preg_replace('/page_id=[0-9]+/','page_id='.$q->query_vars['page_id'], $q->query);
  4961. }
  4962. // p
  4963. if(isset($q->query_vars['p']) && !empty($q->query_vars['p'])){
  4964. $q->query_vars['p'] = icl_object_id($q->query_vars['p'], $post_type, true);
  4965. }
  4966. // name
  4967. if(isset($q->query_vars['name']) && !empty($q->query_vars['name'])){
  4968. $pid = $wpdb->get_var("SELECT ID FROM $wpdb->posts
  4969. WHERE
  4970. post_name='".$wpdb->escape($q->query_vars['name']) .
  4971. "' AND post_type='" . $post_type . "'");
  4972. if (!empty($pid)) {
  4973. $q->query_vars['p'] = icl_object_id($pid, $post_type, true);
  4974. unset($q->query_vars['name']);
  4975. }
  4976. }
  4977. // pagename
  4978. if(isset($q->query_vars['pagename']) && !empty($q->query_vars['pagename'])){
  4979. // find the page with the page name in the current language.
  4980. $pid = $wpdb->get_var($wpdb->prepare("
  4981. SELECT ID
  4982. FROM $wpdb->posts p
  4983. JOIN {$wpdb->prefix}icl_translations t
  4984. ON p.ID = t.element_id AND element_type='post_page'
  4985. WHERE p.post_name=%s AND t.language_code = %s
  4986. ", $q->query_vars['pagename'], $this->get_current_language()));
  4987. if ($pid) {
  4988. $q->query_vars['page_id'] = $pid;
  4989. // We have found the page id
  4990. unset($q->query_vars['pagename']);
  4991. if ( $q->query_vars['page_id'] == get_option('page_for_posts') ) {
  4992. // it's the blog page.
  4993. $wp_query->is_page = false;
  4994. $wp_query->is_home = true;
  4995. $wp_query->is_posts_page = true;
  4996. }
  4997. }
  4998. }
  4999. // post__in
  5000. if(isset($q->query_vars['post__in']) && !empty($q->query_vars['post__in'])){
  5001. $pid = array();
  5002. foreach($q->query_vars['post__in'] as $p){
  5003. if(is_array($post_type)){
  5004. foreach($post_type as $pt){
  5005. $pid[] = icl_object_id($p, $pt, true);
  5006. }
  5007. }
  5008. else{
  5009. $pid[] = icl_object_id($p, $post_type, true);
  5010. }
  5011. }
  5012. $q->query_vars['post__in'] = $pid;
  5013. }
  5014. // post__not_in
  5015. if(isset($q->query_vars['post__not_in']) && !empty($q->query_vars['post__not_in'])){
  5016. $pid = array();
  5017. foreach($q->query_vars['post__not_in'] as $p){
  5018. if(is_array($post_type)){
  5019. foreach($post_type as $pt){
  5020. $pid[] = icl_object_id($p, $pt, true);
  5021. }
  5022. }
  5023. else{
  5024. $pid[] = icl_object_id($p, $post_type, true);
  5025. }
  5026. }
  5027. $q->query_vars['post__not_in'] = $pid;
  5028. }
  5029. // post_parent
  5030. if(isset($q->query_vars['post_parent']) && !empty($q->query_vars['post_parent']) && $q->query_vars['post_type']!='attachment'){
  5031. if(is_array($post_type)){
  5032. $_parent_type = $wpdb->get_var($wpdb->prepare("SELECT post_type FROM {$wpdb->posts} WHERE ID=%d", $q->query_vars['post_parent']));
  5033. $q->query_vars['post_parent'] = icl_object_id($q->query_vars['post_parent'], $_parent_type, true);
  5034. }else{
  5035. $q->query_vars['post_parent'] = icl_object_id($q->query_vars['post_parent'], $post_type, true);
  5036. }
  5037. }
  5038. // custom taxonomies
  5039. if(isset($q->query_vars['taxonomy']) && $q->query_vars['taxonomy']){
  5040. $tax_id = $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->terms} WHERE slug=%s", $q->query_vars['term']));
  5041. if($tax_id){
  5042. $translated_tax_id = icl_object_id($tax_id, $q->query_vars['taxonomy'], true);
  5043. }
  5044. $q->query_vars['term'] = $wpdb->get_var($wpdb->prepare(
  5045. "SELECT slug FROM {$wpdb->terms} WHERE term_id = %d", $translated_tax_id));
  5046. $q->query[$q->query_vars['taxonomy']] = $q->query_vars['term'];
  5047. }
  5048. // TODO Discuss this. Why WP assumes it's there if query vars are altered?
  5049. // Look at wp-includes/query.php line #2468 search: if ( $this->query_vars_changed ) {
  5050. if (!isset($q->query_vars['meta_query'])) {
  5051. $q->query_vars['meta_query'] = array();
  5052. }
  5053. }
  5054. return $q;
  5055. }
  5056. function adjust_wp_list_pages_excludes($pages){
  5057. foreach($pages as $k=>$v){
  5058. $pages[$k] = icl_object_id($v, 'page', true);
  5059. }
  5060. return $pages;
  5061. }
  5062. function language_attributes($output){
  5063. if(preg_match('#lang="[a-z-]+"#i',$output)){
  5064. $output = preg_replace('#lang="([a-z-]+)"#i', 'lang="'.$this->this_lang.'"', $output);
  5065. }else{
  5066. $output .= ' lang="'.$this->this_lang.'"';
  5067. }
  5068. return $output;
  5069. }
  5070. // Localization
  5071. function plugin_localization(){
  5072. load_plugin_textdomain( 'sitepress', false, ICL_PLUGIN_FOLDER . '/locale');
  5073. }
  5074. function locale(){
  5075. global $wpdb, $locale;
  5076. add_filter('language_attributes', array($this, '_language_attributes'));
  5077. if(defined('WP_ADMIN')){
  5078. if( function_exists('wp_get_current_user') && get_user_meta(get_current_user_id(), 'icl_admin_language_for_edit', true) && icl_is_post_edit()){
  5079. $l = $this->get_locale($this->get_current_language());
  5080. }else{
  5081. $l = $this->get_locale($this->admin_language);
  5082. }
  5083. }else{
  5084. $l = $this->get_locale($this->this_lang);
  5085. }
  5086. if($l){
  5087. $locale = $l;
  5088. }
  5089. $template_path = defined('TEMPLATEPATH') ? TEMPLATEPATH : get_template_directory();
  5090. // theme localization
  5091. remove_filter('locale', array($this, 'locale')); //avoid infinite loop
  5092. static $theme_locales_loaded = false;
  5093. if(
  5094. !$theme_locales_loaded
  5095. && !empty($this->settings['theme_localization_load_textdomain'])
  5096. && !empty($this->settings['gettext_theme_domain_name'])
  5097. && !empty($this->settings['theme_language_folders'])
  5098. ){
  5099. foreach($this->settings['theme_language_folders'] as $folder){
  5100. load_textdomain($this->settings['gettext_theme_domain_name'], $folder . '/'.$locale.'.mo');
  5101. }
  5102. $theme_locales_loaded = true;
  5103. }
  5104. add_filter('locale', array($this, 'locale'));
  5105. return $locale;
  5106. }
  5107. function _language_attributes($latr){
  5108. global $locale;
  5109. $latr = preg_replace('#lang="(.[a-z])"#i', 'lang="'.str_replace('_','-',$locale).'"', $latr);
  5110. return $latr;
  5111. }
  5112. function get_locale($code) {
  5113. global $wpdb;
  5114. if (is_null($code)) return false;
  5115. if ($locale = wp_cache_get('icl_locale_get_' . $code)){
  5116. return $locale;
  5117. }
  5118. $locale = $wpdb->get_var($wpdb->prepare("SELECT locale FROM {$wpdb->prefix}icl_locale_map WHERE code=%s", $code));
  5119. wp_cache_set('icl_locale_get_' . $code, $locale);
  5120. return $locale;
  5121. }
  5122. function switch_locale($lang_code = false){
  5123. global $sitepress, $l10n;
  5124. static $original_l10n;
  5125. if(!empty($lang_code)){
  5126. $original_l10n = $l10n['sitepress'];
  5127. unset($l10n['sitepress']);
  5128. load_textdomain('sitepress', ICL_PLUGIN_PATH . '/locale/sitepress-' . $this->get_locale($lang_code).'.mo');
  5129. }else{ // switch back
  5130. $l10n['sitepress'] = $original_l10n;
  5131. }
  5132. }
  5133. function get_locale_file_names(){
  5134. global $wpdb;
  5135. $locales = array();
  5136. $res = $wpdb->get_results("
  5137. SELECT lm.code, locale
  5138. FROM {$wpdb->prefix}icl_locale_map lm JOIN {$wpdb->prefix}icl_languages l ON lm.code = l.code AND l.active=1");
  5139. foreach($res as $row){
  5140. $locales[$row->code] = $row->locale;
  5141. }
  5142. return $locales;
  5143. }
  5144. function set_locale_file_names($locale_file_names_pairs){
  5145. global $wpdb;
  5146. $lfn = $this->get_locale_file_names();
  5147. $new = array_diff(array_keys($locale_file_names_pairs), array_keys($lfn));
  5148. if(!empty($new)){
  5149. foreach($new as $code){
  5150. $wpdb->insert($wpdb->prefix.'icl_locale_map', array('code'=>$code,'locale'=>$locale_file_names_pairs[$code]));
  5151. }
  5152. }
  5153. $remove = array_diff(array_keys($lfn), array_keys($locale_file_names_pairs));
  5154. if(!empty($remove)){
  5155. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_locale_map WHERE code IN (".join(',', array_map(create_function('$a','return "\'".$a."\'";'),$remove)).")");
  5156. }
  5157. $update = array_diff($locale_file_names_pairs, $lfn);
  5158. foreach($update as $code=>$locale){
  5159. $wpdb->update($wpdb->prefix.'icl_locale_map', array('locale'=>$locale), array('code'=>$code));
  5160. }
  5161. $this->icl_locale_cache->clear();
  5162. return true;
  5163. }
  5164. function pre_option_page_on_front(){
  5165. global $wpdb;
  5166. static $page_on_front_sc = array();
  5167. if (!isset($page_on_front_sc[$this->this_lang]) || ICL_DISABLE_CACHE) {
  5168. $page_on_front_sc[$this->this_lang] = false;
  5169. $page_on_front = $wpdb->get_var("SELECT option_value FROM {$wpdb->options} WHERE option_name='page_on_front'");
  5170. $_el_lang_det = $this->get_element_language_details($page_on_front, 'post_page');
  5171. if(!empty($_el_lang_det->trid)){
  5172. $trid = $_el_lang_det->trid;
  5173. $translations = $wpdb->get_results("SELECT element_id, language_code FROM {$wpdb->prefix}icl_translations WHERE trid={$trid}");
  5174. foreach($translations as $t){
  5175. if($t->language_code==$this->this_lang){
  5176. $page_on_front_sc[$this->this_lang] = $t->element_id;
  5177. }
  5178. }
  5179. }
  5180. }
  5181. return $page_on_front_sc[$this->this_lang];
  5182. }
  5183. function pre_option_page_for_posts(){
  5184. global $wpdb;
  5185. static $page_for_posts_sc = array();
  5186. if (!isset($page_for_posts_sc[$this->this_lang]) || ICL_DISABLE_CACHE) {
  5187. $page_for_posts_sc[$this->this_lang] = false;
  5188. $page_for_posts = $wpdb->get_var("SELECT option_value FROM {$wpdb->options} WHERE option_name='page_for_posts'");
  5189. $_el_lang_det = $this->get_element_language_details($page_for_posts, 'post_page');
  5190. if(!empty($_el_lang_det->trid)){
  5191. $trid = $_el_lang_det->trid;
  5192. $translations = $wpdb->get_results("SELECT element_id, language_code FROM {$wpdb->prefix}icl_translations WHERE trid={$trid}");
  5193. foreach($translations as $t){
  5194. if($t->language_code==$this->this_lang){
  5195. $page_for_posts_sc[$this->this_lang] = $t->element_id;
  5196. }
  5197. }
  5198. }
  5199. }
  5200. return $page_for_posts_sc[$this->this_lang];
  5201. }
  5202. function verify_home_and_blog_pages_translations(){
  5203. global $wpdb;
  5204. $warn_home = $warn_posts = '';
  5205. if( 'page' == get_option('show_on_front') && get_option('page_on_front')){
  5206. $page_on_front = get_option('page_on_front');
  5207. $page_home_trid = $wpdb->get_var("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id={$page_on_front} AND element_type='post_page'");
  5208. $page_home_translations = $this->get_element_translations($page_home_trid, 'post_page');
  5209. $missing_home = array();
  5210. foreach($this->active_languages as $lang){
  5211. if(!isset($page_home_translations[$lang['code']])){
  5212. $addlink = admin_url('post-new.php?post_type=page&trid='.$page_home_trid.'&lang=' . $lang['code'] . '&source_lang=' . $this->get_default_language());
  5213. //$missing_home[] = '<a href="'.$addlink.'" title="'.__('add translation', 'sitepress').'">' . $lang['display_name'] . '</a>';
  5214. $missing_home[] = $lang['display_name'];
  5215. }elseif($page_home_translations[$lang['code']]->post_status != 'publish'){
  5216. $editlink = admin_url('post.php?post='.$page_home_translations[$lang['code']]->element_id.'&action=edit&lang='.$lang['code']);
  5217. //$missing_home[] = '<a href="'.$editlink.'" title="'.__('Not published - edit page', 'sitepress').'">' . $lang['display_name'] . '</a>';
  5218. $missing_home[] = $lang['display_name'];
  5219. }
  5220. }
  5221. if(!empty($missing_home)){
  5222. $warn_home = '<div class="icl_form_errors" style="font-weight:bold">';
  5223. $warn_home .= sprintf(__('Your home page does not exist or its translation is not published in %s.', 'sitepress'), join(', ', $missing_home));
  5224. $warn_home .= '<br />';
  5225. $warn_home .= '<a href="'.get_edit_post_link($page_on_front).'">' . __('Edit this page to add translations', 'sitepress') . '</a>';
  5226. $warn_home .= '</div>';
  5227. }
  5228. }
  5229. if(get_option('page_for_posts')){
  5230. $page_for_posts = get_option('page_for_posts');
  5231. $page_posts_trid = $wpdb->get_var("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id={$page_for_posts} AND element_type='post_page'");
  5232. $page_posts_translations = $this->get_element_translations($page_posts_trid, 'post_page');
  5233. $missing_posts = array();
  5234. foreach($this->active_languages as $lang){
  5235. if(!isset($page_posts_translations[$lang['code']])){
  5236. $addlink = admin_url('post-new.php?post_type=page&trid='.$page_posts_trid.'&lang=' . $lang['code'] . '&source_lang=' . $this->get_default_language());
  5237. //$missing_posts[] = '<a href="'.$addlink.'" title="'.__('add translation', 'sitepress').'">' . $lang['display_name'] . '</a>';
  5238. $missing_posts[] = $lang['display_name'];
  5239. }elseif($page_posts_translations[$lang['code']]->post_status != 'publish'){
  5240. $editlink = admin_url('post.php?post='.$page_posts_translations[$lang['code']]->element_id.'&action=edit&lang='.$lang['code']);
  5241. //$missing_posts[] = '<a href="'.$editlink.'" title="'.__('Not published - edit page', 'sitepress').'">' . $lang['display_name'] . '</a>';
  5242. $missing_posts[] = $lang['display_name'];
  5243. }
  5244. }
  5245. if(!empty($missing_posts)){
  5246. $warn_posts = '<div class="icl_form_errors" style="font-weight:bold;margin-top:4px;">';
  5247. $warn_posts .= sprintf(__('Your blog page does not exist or its translation is not published in %s.', 'sitepress'), join(', ', $missing_posts));
  5248. $warn_posts .= '<br />';
  5249. $warn_posts .= '<a href="'.get_edit_post_link($page_for_posts).'">' . __('Edit this page to add translations', 'sitepress') . '</a>';
  5250. $warn_posts .= '</div>';
  5251. }
  5252. }
  5253. return array($warn_home, $warn_posts);
  5254. }
  5255. // adds the language parameter to the admin post filtering/search
  5256. function restrict_manage_posts(){
  5257. echo '<input type="hidden" name="lang" value="'.$this->this_lang.'" />';
  5258. }
  5259. // adds the language parameter to the admin pages search
  5260. function restrict_manage_pages(){
  5261. ?>
  5262. <script type="text/javascript">
  5263. addLoadEvent(function(){jQuery('p.search-box').append('<input type="hidden" name="lang" value="<?php echo $this->this_lang ?>">');});
  5264. </script>
  5265. <?php
  5266. }
  5267. function get_edit_post_link($link, $id, $context = 'display'){
  5268. global $wpdb;
  5269. static $_cache;
  5270. $_cache_key = $link.'|'.$id.'|'.$context;
  5271. if(isset($_cache[$_cache_key])){
  5272. $link = $_cache[$_cache_key];
  5273. }else{
  5274. if ( current_user_can( 'edit_post', $id ) ) {
  5275. if ( 'display' == $context )
  5276. $and = '&amp;';
  5277. else
  5278. $and = '&';
  5279. if($id){
  5280. $post_type = $wpdb->get_var("SELECT post_type FROM {$wpdb->posts} WHERE ID='{$id}'");
  5281. $details = $this->get_element_language_details($id, 'post_' . $post_type);
  5282. if(isset($details->language_code)){
  5283. $lang = $details->language_code;
  5284. }else{
  5285. $lang = $this->get_current_language();
  5286. }
  5287. if($lang != $this->get_default_language() || $this->get_current_language() != $this->get_default_language()){
  5288. $link .= $and . 'lang=' . $lang;
  5289. }
  5290. }
  5291. }
  5292. $_cache[$_cache_key] = $link;
  5293. }
  5294. return $link;
  5295. }
  5296. function get_edit_term_link($link, $term_id, $taxonomy, $object_type){
  5297. global $wpdb;
  5298. $term_tax_id = $wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", $term_id, $taxonomy));
  5299. $details = $this->get_element_language_details($term_tax_id, 'tax_' . $taxonomy);
  5300. $and = '&';
  5301. if(isset($details->language_code)){
  5302. $lang = $details->language_code;
  5303. }else{
  5304. $lang = $this->get_current_language();
  5305. }
  5306. if($lang != $this->get_default_language() || $this->get_current_language() != $this->get_default_language()){
  5307. $link .= $and . 'lang=' . $lang;
  5308. }
  5309. return $link;
  5310. }
  5311. function option_sticky_posts($posts){
  5312. global $wpdb;
  5313. if(is_array($posts) && !empty($posts)){
  5314. $posts = array_filter($posts, create_function('$a', 'return $a > 0;'));
  5315. $posts = $wpdb->get_col("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_id IN (".join(',',$posts).") AND element_type='post_post' AND language_code = '{$this->this_lang}'");
  5316. }
  5317. return $posts;
  5318. }
  5319. function request_filter($request){
  5320. // bug http://forum.wpml.org/topic.php?id=5
  5321. if(!defined('WP_ADMIN') && $this->settings['language_negotiation_type']==3 && isset($request['lang'])) {
  5322. // Count the parameters that have settings and remove our 'lang ' setting it's the only one.
  5323. // This is required so that home page detection works for other languages.
  5324. $count = 0;
  5325. foreach ($request as $data) {
  5326. if ($data !== '') {
  5327. $count += 1;
  5328. }
  5329. }
  5330. if ($count == 1) {
  5331. unset($request['lang']);
  5332. }
  5333. }
  5334. return $request;
  5335. }
  5336. function noscript_notice(){
  5337. ?><noscript><div class="error"><?php echo __('WPML admin screens require JavaScript in order to display. JavaScript is currently off in your browser.', 'sitepress') ?></div></noscript><?php
  5338. }
  5339. function filter_queries($sql){
  5340. global $wpdb, $pagenow;
  5341. // keep a record of the queries
  5342. $this->queries[] = $sql;
  5343. if($pagenow=='categories.php' || $pagenow=='edit-tags.php'){
  5344. if(preg_match('#^SELECT COUNT\(\*\) FROM '.$wpdb->term_taxonomy.' WHERE taxonomy = \'(category|post_tag)\' $#',$sql,$matches)){
  5345. $element_type= 'tax_' . $matches[1];
  5346. $sql = "
  5347. SELECT COUNT(*) FROM {$wpdb->term_taxonomy} tx
  5348. JOIN {$wpdb->prefix}icl_translations tr ON tx.term_taxonomy_id=tr.element_id
  5349. WHERE tx.taxonomy='{$matches[1]}' AND tr.element_type='{$element_type}' AND tr.language_code='".$this->get_current_language()."'";
  5350. }
  5351. }
  5352. if($pagenow=='edit.php' || $pagenow=='edit-pages.php'){
  5353. $post_type = isset($_GET['post_type']) ? $_GET['post_type'] : 'post';
  5354. $element_type = 'post_' . $post_type;
  5355. if($this->is_translated_post_type($post_type)){
  5356. if(preg_match('#SELECT post_status, COUNT\( \* \) AS num_posts FROM '.$wpdb->posts.' WHERE post_type = \'(.+)\' GROUP BY post_status#i',$sql,$matches)){
  5357. if('all'!=$this->get_current_language()){
  5358. $sql = '
  5359. SELECT post_status, COUNT( * ) AS num_posts
  5360. FROM '.$wpdb->posts.' p
  5361. JOIN '.$wpdb->prefix.'icl_translations t ON p.ID = t.element_id
  5362. WHERE p.post_type = \''.$matches[1].'\'
  5363. AND t.element_type=\''.$element_type.'\'
  5364. AND t.language_code=\''.$this->get_current_language().'\'
  5365. GROUP BY post_status';
  5366. }else{
  5367. $sql = '
  5368. SELECT post_status, COUNT( * ) AS num_posts
  5369. FROM '.$wpdb->posts.' p
  5370. JOIN '.$wpdb->prefix.'icl_translations t ON p.ID = t.element_id
  5371. JOIN '.$wpdb->prefix.'icl_languages l ON t.language_code = l.code AND l.active = 1
  5372. WHERE p.post_type = \''.$matches[1].'\'
  5373. AND t.element_type=\''.$element_type.'\'
  5374. GROUP BY post_status';
  5375. }
  5376. }
  5377. }
  5378. }
  5379. if(isset($_GET['action']) && $_GET['action']=='ajax-tag-search'){
  5380. $search = 'SELECT t.name FROM '. $wpdb->term_taxonomy
  5381. .' AS tt INNER JOIN '.$wpdb->terms.' AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = \''. $wpdb->escape($_GET['tax'])
  5382. .'\' AND t.name LIKE (\'%' . $wpdb->escape($_GET['q']) . '%\')';
  5383. if($sql == $search){
  5384. $parts = parse_url($_SERVER['HTTP_REFERER']);
  5385. @parse_str($parts['query'], $query);
  5386. $lang = isset($query['lang']) ? $query['lang'] : $this->get_language_cookie();
  5387. $element_type = 'tax_' . $_GET['tax'];
  5388. $sql =
  5389. 'SELECT t.name FROM '. $wpdb->term_taxonomy
  5390. .' AS tt
  5391. INNER JOIN '.$wpdb->terms.' AS t ON tt.term_id = t.term_id
  5392. JOIN '.$wpdb->prefix.'icl_translations tr ON tt.term_taxonomy_id = tr.element_id
  5393. WHERE tt.taxonomy = \''. $wpdb->escape($_GET['tax'])
  5394. .'\' AND tr.language_code=\''.$lang.'\' AND element_type=\''.$element_type.'\'
  5395. AND t.name LIKE (\'%' . $wpdb->escape($_GET['q']) . '%\')
  5396. ';
  5397. }
  5398. }
  5399. // filter get page by path WP 3.3+
  5400. if( preg_match("#SELECT ID, post_name, post_parent FROM {$wpdb->posts} WHERE post_name IN \(([^)]+)\) AND \(post_type = '([^']+)' OR post_type = 'attachment'\)#", $sql, $matches) ){
  5401. $sql = "SELECT p.ID, p.post_name, p.post_parent
  5402. FROM {$wpdb->posts} p
  5403. LEFT JOIN {$wpdb->prefix}icl_translations t on t.element_id = p.ID AND t.element_type = 'post_{$matches[2]}' AND t.language_code='" . $this->get_current_language() . "'
  5404. WHERE p.post_name IN ({$matches[1]}) AND (p.post_type = '{$matches[2]}' OR p.post_type = 'attachment')
  5405. ORDER BY t.language_code='" . $this->get_current_language() . "' DESC
  5406. ";
  5407. // added order by to ensure that we get the result in teh current language first
  5408. }
  5409. // filter get page by path < WP 3.3
  5410. elseif( preg_match("#SELECT ID, post_name, post_parent FROM {$wpdb->posts} WHERE post_name = '([^']+)' AND \(post_type = '([^']+)' OR post_type = 'attachment'\)#", $sql, $matches) ){
  5411. $sql = "SELECT p.ID, p.post_name, p.post_parent
  5412. FROM {$wpdb->posts} p
  5413. JOIN {$wpdb->prefix}icl_translations t on t.element_id = p.ID AND t.element_type = 'post_{$matches[2]}'
  5414. WHERE p.post_name = '{$matches[1]}' AND (p.post_type = '{$matches[2]}' OR p.post_type = 'attachment')
  5415. AND t.language_code='" . $this->get_current_language() . "'";
  5416. }
  5417. // filter calendar widget queries
  5418. //elseif( preg_match("##", $sql, $matches) ){
  5419. //
  5420. //}
  5421. return $sql;
  5422. }
  5423. function get_inactive_content(){
  5424. global $wpdb;
  5425. $inactive = array();
  5426. $res_p = $wpdb->get_results("
  5427. SELECT COUNT(p.ID) AS c, p.post_type, lt.name AS language FROM {$wpdb->prefix}icl_translations t
  5428. JOIN {$wpdb->posts} p ON t.element_id=p.ID AND t.element_type LIKE 'post\\_%'
  5429. JOIN {$wpdb->prefix}icl_languages l ON t.language_code = l.code AND l.active = 0
  5430. JOIN {$wpdb->prefix}icl_languages_translations lt ON lt.language_code = l.code AND lt.display_language_code='".$this->get_current_language()."'
  5431. GROUP BY p.post_type, t.language_code
  5432. ");
  5433. foreach($res_p as $r){
  5434. $inactive[$r->language][$r->post_type] = $r->c;
  5435. }
  5436. $res_t = $wpdb->get_results("
  5437. SELECT COUNT(p.term_taxonomy_id) AS c, p.taxonomy, lt.name AS language FROM {$wpdb->prefix}icl_translations t
  5438. JOIN {$wpdb->term_taxonomy} p ON t.element_id=p.term_taxonomy_id
  5439. JOIN {$wpdb->prefix}icl_languages l ON t.language_code = l.code AND l.active = 0
  5440. JOIN {$wpdb->prefix}icl_languages_translations lt ON lt.language_code = l.code AND lt.display_language_code='".$this->get_current_language()."'
  5441. WHERE t.element_type LIKE 'tax\\_%'
  5442. GROUP BY p.taxonomy, t.language_code
  5443. ");
  5444. foreach($res_t as $r){
  5445. if($r->taxonomy=='category' && $r->c == 1){
  5446. continue; //ignore the case of just the default category that gets automatically created for a new language
  5447. }
  5448. $inactive[$r->language][$r->taxonomy] = $r->c;
  5449. }
  5450. return $inactive;
  5451. }
  5452. function menu_footer(){
  5453. include ICL_PLUGIN_PATH . '/menu/menu-footer.php';
  5454. }
  5455. function _allow_calling_template_file_directly(){
  5456. if(is_404()){
  5457. global $wp_query, $wpdb;
  5458. $parts = parse_url(get_bloginfo('url'));
  5459. if(!isset($parts['path'])) $parts['path'] = '';
  5460. $req = str_replace($parts['path'], '', $_SERVER['REQUEST_URI']);
  5461. if(file_exists(ABSPATH . $req) && !is_dir(ABSPATH . $req)){
  5462. $wp_query->is_404 = false;
  5463. header('HTTP/1.1 200 OK');
  5464. include ABSPATH . $req;
  5465. exit;
  5466. }
  5467. }
  5468. }
  5469. function show_user_options(){
  5470. global $current_user;
  5471. $active_languages = $this->get_active_languages();
  5472. $default_language = $this->get_default_language();
  5473. $user_language = get_user_meta($current_user->data->ID,'icl_admin_language',true);
  5474. if($this->settings['admin_default_language'] == '_default_'){
  5475. $this->settings['admin_default_language'] = $default_language;
  5476. }
  5477. $lang_details = $this->get_language_details($this->settings['admin_default_language']);
  5478. $admin_default_language = $lang_details['display_name'];
  5479. ?>
  5480. <a name="wpml"></a>
  5481. <h3><?php _e('WPML language settings','sitepress'); ?></h3>
  5482. <table class="form-table">
  5483. <tbody>
  5484. <tr>
  5485. <th><?php _e('Select your language:', 'sitepress') ?></th>
  5486. <td>
  5487. <select name="icl_user_admin_language">
  5488. <option value=""<?php if($user_language==$this->settings['admin_default_language']) echo ' selected="selected"'?>><?php printf(__('Default admin language (currently %s)','sitepress'), $admin_default_language );?>&nbsp;</option>
  5489. <?php foreach($active_languages as $al):?>
  5490. <option value="<?php echo $al['code'] ?>"<?php if($user_language==$al['code']) echo ' selected="selected"'?>><?php echo $al['display_name']; if($this->admin_language != $al['code']) echo ' ('. $al['native_name'] .')'; ?>&nbsp;</option>
  5491. <?php endforeach; ?>
  5492. </select>
  5493. <span class="description"><?php _e('this will be your admin language and will also be used for translating comments.', 'sitepress'); ?></span>
  5494. <br />
  5495. <label><input type="checkbox" name="icl_admin_language_for_edit" value="1" <?php if(get_user_meta(get_current_user_id(), 'icl_admin_language_for_edit', true)):?>checked="checked"<?php endif;?> />&nbsp;<?php _e('Set admin language as editing language.', 'sitepress'); ?></label>
  5496. </td>
  5497. </tr>
  5498. <tr>
  5499. <th><?php _e('Hidden languages:', 'sitepress') ?></th>
  5500. <td>
  5501. <p>
  5502. <?php if(!empty($this->settings['hidden_languages'])): ?>
  5503. <?php
  5504. if(1 == count($this->settings['hidden_languages'])){
  5505. printf(__('%s is currently hidden to visitors.', 'sitepress'),
  5506. $active_languages[$this->settings['hidden_languages'][0]]['display_name']);
  5507. }else{
  5508. foreach($this->settings['hidden_languages'] as $l){
  5509. $_hlngs[] = $active_languages[$l]['display_name'];
  5510. }
  5511. $hlangs = join(', ', $_hlngs);
  5512. printf(__('%s are currently hidden to visitors.', 'sitepress'), $hlangs);
  5513. }
  5514. ?>
  5515. <?php else: ?>
  5516. <?php _e('All languages are currently displayed. Choose what to do when site languages are hidden.', 'sitepress'); ?>
  5517. <?php endif; ?>
  5518. </p>
  5519. <p>
  5520. <label><input name="icl_show_hidden_languages" type="checkbox" value="1" <?php
  5521. if(get_user_meta($current_user->data->ID, 'icl_show_hidden_languages', true)):?>checked="checked"<?php endif?> />&nbsp;<?php
  5522. _e('Display hidden languages', 'sitepress') ?></label>
  5523. </p>
  5524. </td>
  5525. </tr>
  5526. </tbody>
  5527. </table>
  5528. <?php
  5529. }
  5530. function save_user_options(){
  5531. $user_id = $_POST['user_id'];
  5532. if($user_id){
  5533. update_user_meta($user_id,'icl_admin_language',$_POST['icl_user_admin_language']);
  5534. update_user_meta($user_id,'icl_show_hidden_languages',intval($_POST['icl_show_hidden_languages']));
  5535. update_user_meta($user_id,'icl_admin_language_for_edit',intval($_POST['icl_admin_language_for_edit']));
  5536. $this->icl_locale_cache->clear();
  5537. }
  5538. }
  5539. function help_admin_notice(){
  5540. $q = http_build_query(array(
  5541. 'name' => 'wpml-intro',
  5542. 'iso' => defined('WPLANG') ? WPLANG : '',
  5543. 'src' => get_option('home')
  5544. ));
  5545. ?>
  5546. <br clear="all" />
  5547. <div id="message" class="updated message fade" style="clear:both;margin-top:5px;"><p>
  5548. <?php _e('WPML is a powerful plugin with many features. Would you like to see a quick overview?', 'sitepress'); ?>
  5549. </p>
  5550. <p>
  5551. <a href="<?php echo ICL_API_ENDPOINT ?>/destinations/go?<?php echo $q ?>" target="_blank" class="button-primary"><?php _e('Yes', 'sitepress')?></a>&nbsp;
  5552. <input type="hidden" id="icl_dismiss_help_nonce" value="<?php echo $icl_dhn = wp_create_nonce('dismiss_help_nonce') ?>" />
  5553. <a href="admin.php?page=<?php echo basename(ICL_PLUGIN_PATH).'/menu/languages.php&icl_action=dismiss_help&_icl_nonce=' . $icl_dhn; ?>" class="button"><?php _e('No thanks, I will configure myself', 'sitepress')?></a>&nbsp;
  5554. <a title="<?php _e('Stop showing this message', 'sitepress') ?>" id="icl_dismiss_help" href=""><?php _e('Dismiss', 'sitepress')?></a>
  5555. </p>
  5556. </div>
  5557. <?php
  5558. }
  5559. function upgrade_notice(){
  5560. include ICL_PLUGIN_PATH . '/menu/upgrade_notice.php';
  5561. }
  5562. function icl_reminders(){
  5563. include ICL_PLUGIN_PATH . '/menu/icl_reminders.php';
  5564. }
  5565. function add_posts_management_column($columns){
  5566. global $posts, $wpdb, $__management_columns_posts_translations;
  5567. $element_type = isset($_REQUEST['post_type']) ? 'post_' . $_REQUEST['post_type'] : 'post_post';
  5568. if(count($this->get_active_languages()) <= 1 || get_query_var('post_status') == 'trash'){
  5569. return $columns;
  5570. }
  5571. if(isset($_POST['action']) && $_POST['action']=='inline-save' && $_POST['post_ID']){
  5572. $p = new stdClass();
  5573. $p->ID = $_POST['post_ID'];
  5574. $posts = array($p);
  5575. }elseif(empty($posts)){
  5576. return $columns;
  5577. }
  5578. if(is_null($__management_columns_posts_translations)){
  5579. foreach($posts as $p){
  5580. $post_ids[] = $p->ID;
  5581. }
  5582. // get posts translations
  5583. // get trids
  5584. $trids = $wpdb->get_col("
  5585. SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_type='{$element_type}' AND element_id IN (".join(',', $post_ids).")
  5586. ");
  5587. $ptrs = $wpdb->get_results("
  5588. SELECT trid, element_id, language_code, source_language_code FROM {$wpdb->prefix}icl_translations WHERE trid IN (".join(',', $trids).")
  5589. ");
  5590. foreach($ptrs as $v){
  5591. $by_trid[$v->trid][] = $v;
  5592. }
  5593. foreach($ptrs as $v){
  5594. if(in_array($v->element_id, $post_ids)){
  5595. $el_trid = $v->trid;
  5596. foreach($ptrs as $val){
  5597. if($val->trid == $el_trid){
  5598. $__management_columns_posts_translations[$v->element_id][$val->language_code] = $val;
  5599. }
  5600. }
  5601. }
  5602. }
  5603. }
  5604. $active_languages = $this->get_active_languages();
  5605. foreach($active_languages as $k=>$v){
  5606. if($v['code']==$this->get_current_language()) continue;
  5607. $langs[] = $v['code'];
  5608. }
  5609. $res = $wpdb->get_results("
  5610. SELECT f.lang_code, f.flag, f.from_template, l.name
  5611. FROM {$wpdb->prefix}icl_flags f
  5612. JOIN {$wpdb->prefix}icl_languages_translations l ON f.lang_code = l.language_code
  5613. WHERE l.display_language_code = '".$this->admin_language."' AND f.lang_code IN('".join("','",$langs)."')
  5614. ");
  5615. foreach($res as $r){
  5616. if($r->from_template){
  5617. $fpath = get_bloginfo('template_directory') . '/images/flags/';
  5618. }else{
  5619. } $fpath = ICL_PLUGIN_URL . '/res/flags/';
  5620. $flags[$r->lang_code] = '<img src="'.$fpath.$r->flag.'" width="18" height="12" alt="'.$r->name.'" title="'.$r->name.'" />';
  5621. }
  5622. $colh = '';
  5623. foreach($active_languages as $v){
  5624. if(isset($flags[$v['code']])) $colh .= $flags[$v['code']];
  5625. }
  5626. foreach($columns as $k=>$v){
  5627. $new_columns[$k] = $v;
  5628. if($k=='title'){
  5629. $new_columns['icl_translations'] = $colh;
  5630. }
  5631. }
  5632. return $new_columns;
  5633. }
  5634. function add_content_for_posts_management_column($column_name){
  5635. global $wpdb, $sitepress_settings;
  5636. if($column_name != 'icl_translations') return;
  5637. global $id, $__management_columns_posts_translations, $pagenow, $iclTranslationManagement;
  5638. $active_languages = $this->get_active_languages();
  5639. foreach($active_languages as $k=>$v){
  5640. if($v['code']==$this->get_current_language()) continue;
  5641. $post_type = isset($_REQUEST['post_type']) ? $_REQUEST['post_type'] : 'post';
  5642. if(isset($__management_columns_posts_translations[$id][$v['code']]) && $__management_columns_posts_translations[$id][$v['code']]->element_id){
  5643. // Translation exists
  5644. $img = 'edit_translation.png';
  5645. $alt = sprintf(__('Edit the %s translation','sitepress'), $v['display_name']);
  5646. switch($iclTranslationManagement->settings['doc_translation_method']){
  5647. case ICL_TM_TMETHOD_EDITOR:
  5648. $job_id = $iclTranslationManagement->get_translation_job_id($__management_columns_posts_translations[$id][$v['code']]->trid, $v['code']);
  5649. $args = array('lang_from'=>$this->get_current_language(), 'lang_to'=>$v['code'], 'job_id'=>@intval($job_id));
  5650. // is a translator of this document?
  5651. $current_user_is_translator = $iclTranslationManagement->is_translator(get_current_user_id(), $args);
  5652. if(!$current_user_is_translator){
  5653. $img = 'edit_translation_disabled.png';
  5654. $link = '#';
  5655. // is a translator of this language?
  5656. unset($args['job_id']);
  5657. $current_user_is_translator = $iclTranslationManagement->is_translator(get_current_user_id(), $args);
  5658. if($current_user_is_translator){
  5659. $alt = sprintf(__("You can't edit this translation because you're not the translator. <a%s>Learn more.</a>",'sitepress'), ' href="http://wpml.org/?page_id=52218"');
  5660. }else{
  5661. $alt = sprintf(__("You can't edit this translation because you're not a %s translator. <a%s>Learn more.</a>",'sitepress'), $v['display_name'], ' href="http://wpml.org/?page_id=52218"');
  5662. }
  5663. }else{
  5664. if($job_id){
  5665. $link = admin_url('admin.php?page='.WPML_TM_FOLDER.'/menu/translations-queue.php&job_id='.$job_id);
  5666. }else{
  5667. $link = admin_url('admin.php?page='.WPML_TM_FOLDER.'/menu/translations-queue.php&icl_tm_action=create_job&iclpost[]='.
  5668. $id.'&translate_to['.$v['code'].']=1&iclnonce=' . wp_create_nonce('pro-translation-icl'));
  5669. }
  5670. }
  5671. break;
  5672. case ICL_TM_TMETHOD_PRO:
  5673. if(!$__management_columns_posts_translations[$id][$v['code']]->source_language_code){
  5674. $link = get_edit_post_link($__management_columns_posts_translations[$id][$v['code']]->element_id);
  5675. $alt = __('Edit the original document','sitepress');
  5676. }else{
  5677. $job_id = $iclTranslationManagement->get_translation_job_id($__management_columns_posts_translations[$id][$v['code']]->trid, $v['code']);
  5678. if($job_id){
  5679. $job_details = $iclTranslationManagement->get_translation_job($job_id);
  5680. if($job_details->status == ICL_TM_IN_PROGRESS || $job_details->status == ICL_TM_WAITING_FOR_TRANSLATOR){
  5681. $img = 'in-progress.png';
  5682. $alt = sprintf(__('Translation to %s is in progress','sitepress'), $v['display_name']);
  5683. $link = false;
  5684. echo '<img style="padding:1px;margin:2px;" border="0" src="'.ICL_PLUGIN_URL . '/res/img/' .$img.'" title="'.$alt.'" alt="'.$alt.'" width="16" height="16" />';
  5685. }else{
  5686. $link = admin_url('admin.php?page='.WPML_TM_FOLDER.'/menu/translations-queue.php&job_id='.$job_id);
  5687. }
  5688. }
  5689. }
  5690. break;
  5691. default:
  5692. $link = 'post.php?post_type='.$post_type.'&action=edit&amp;post='.$__management_columns_posts_translations[$id][$v['code']]->element_id.'&amp;lang='.$v['code'];
  5693. }
  5694. }else{
  5695. // Translation does not exist
  5696. $img = 'add_translation.png';
  5697. $alt = sprintf(__('Add translation to %s','sitepress'), $v['display_name']);
  5698. $src_lang = $this->get_current_language() == 'all' ? $this->get_default_language() : $this->get_current_language();
  5699. switch($iclTranslationManagement->settings['doc_translation_method']){
  5700. case ICL_TM_TMETHOD_EDITOR:
  5701. if(isset($__management_columns_posts_translations[$id][$v['code']])){
  5702. $job_id = $iclTranslationManagement->get_translation_job_id($__management_columns_posts_translations[$id][$v['code']]->trid, $v['code']);
  5703. }else{
  5704. $job_id = 0;
  5705. }
  5706. $args = array('lang_from'=>$src_lang, 'lang_to'=>$v['code'], 'job_id'=>@intval($job_id));
  5707. $current_user_is_translator = $iclTranslationManagement->is_translator(get_current_user_id(), $args);
  5708. if($job_id){
  5709. if($current_user_is_translator){
  5710. $job_details = $iclTranslationManagement->get_translation_job($job_id);
  5711. if($job_details && $job_details->status == ICL_TM_IN_PROGRESS){
  5712. $img = 'in-progress.png';
  5713. $alt = sprintf(__('Translation to %s is in progress','sitepress'), $v['display_name']);
  5714. }
  5715. $link = admin_url('admin.php?page='.WPML_TM_FOLDER.'/menu/translations-queue.php&job_id='.$job_id);
  5716. }else{
  5717. $link = '#';
  5718. $tres = $wpdb->get_row($wpdb->prepare("
  5719. SELECT s.* FROM {$wpdb->prefix}icl_translation_status s
  5720. JOIN {$wpdb->prefix}icl_translate_job j ON j.rid = s.rid
  5721. WHERE job_id=%d
  5722. ", $job_id));
  5723. if($tres->status == ICL_TM_IN_PROGRESS){
  5724. $img = 'in-progress.png';
  5725. $alt = sprintf(__('Translation to %s is in progress (by a different translator)','sitepress'), $v['display_name']);
  5726. }elseif($tres->status == ICL_TM_NOT_TRANSLATED || $tres->status == ICL_TM_WAITING_FOR_TRANSLATOR){
  5727. $img = 'add_translation_disabled.png';
  5728. $alt = sprintf(__('Translation to %s is in progress (by a different translator)','sitepress'), $v['display_name']);
  5729. }elseif($tres->status == ICL_TM_NEEDS_UPDATE || $tres->status == ICL_TM_COMPLETE){
  5730. $img = 'edit_translation_disabled.png';
  5731. $alt = sprintf(__('Translation to %s is maintained by a different translator','sitepress'), $v['display_name']);
  5732. }
  5733. }
  5734. }else{
  5735. if($current_user_is_translator){
  5736. $link = admin_url('admin.php?page='.WPML_TM_FOLDER.'/menu/translations-queue.php&icl_tm_action=create_job&iclpost[]='.
  5737. $id.'&translate_to['.$v['code'].']=1&iclnonce=' . wp_create_nonce('pro-translation-icl'));
  5738. }else{
  5739. $link = '#';
  5740. $img = 'add_translation_disabled.png';
  5741. $alt = sprintf(__("You can't add this translation because you're not a %s translator. <a%s>Learn more.</a>",'sitepress'), $v['display_name'], ' href="http://wpml.org/?page_id=52218"');
  5742. }
  5743. }
  5744. break;
  5745. case ICL_TM_TMETHOD_PRO:
  5746. if($this->have_icl_translator($src_lang,$v['code'])){
  5747. if(!isset($__management_columns_posts_translations[$id][$v['code']]))
  5748. $job_id = false;
  5749. else
  5750. $job_id = @$iclTranslationManagement->get_translation_job_id($__management_columns_posts_translations[$id][$v['code']]->trid, $v['code']);
  5751. if($job_id){
  5752. $job_details = $iclTranslationManagement->get_translation_job($job_id);
  5753. if($job_details->status == ICL_TM_IN_PROGRESS || $job_details->status == ICL_TM_WAITING_FOR_TRANSLATOR){
  5754. $img = 'in-progress.png';
  5755. $alt = sprintf(__('Translation to %s is in progress','sitepress'), $v['display_name']);
  5756. $link = false;
  5757. echo '<img style="padding:1px;margin:2px;" border="0" src="'.ICL_PLUGIN_URL . '/res/img/' .$img.'" title="'.$alt.'" alt="'.$alt.'" width="16" height="16" />';
  5758. }else{
  5759. $link = admin_url('admin.php?page='.WPML_TM_FOLDER.'/menu/translations-queue.php&job_id='.$job_id);
  5760. }
  5761. }else{
  5762. $qs = array();
  5763. if(!empty($_SERVER['QUERY_STRING']))
  5764. foreach($_exp = explode('&', $_SERVER['QUERY_STRING']) as $q=>$qv){
  5765. $__exp = explode('=', $qv);
  5766. $__exp[0] = preg_replace('#\[(.*)\]#', '', $__exp[0]);
  5767. if(!in_array($__exp[0], array('icl_tm_action', 'translate_from', 'translate_to', 'iclpost', 'service', 'iclnonce'))){
  5768. $qs[$q] = $qv;
  5769. }
  5770. }
  5771. $link = admin_url('edit.php?'.join('&', $qs).'&icl_tm_action=send_jobs&translate_from='.$src_lang
  5772. .'&translate_to['.$v['code'].']=1&iclpost[]='.$id
  5773. .'&service=icanlocalize&iclnonce=' . wp_create_nonce('pro-translation-icl'));
  5774. }
  5775. }else{
  5776. $link = false;
  5777. $alt = sprintf(__('Get %s translators','sitepress'), $v['display_name']);
  5778. $img = 'add_translators.png';
  5779. echo $this->create_icl_popup_link("@select-translators;{$src_lang};{$v['code']}@",
  5780. array(
  5781. 'ar'=>1,
  5782. 'title'=>$alt,
  5783. 'unload_cb' => 'icl_pt_reload_translation_box'
  5784. )
  5785. ) . '<img style="padding:1px;margin:2px;" border="0" src="'.ICL_PLUGIN_URL . '/res/img/' .$img.'" alt="'.$alt.'" width="16" height="16" />' . '</a>';
  5786. }
  5787. break;
  5788. default:
  5789. $link = 'post-new.php?post_type='.$post_type.'&trid='
  5790. . $__management_columns_posts_translations[$id][$src_lang]->trid.'&amp;lang='.$v['code'].'&amp;source_lang=' . $src_lang;
  5791. }
  5792. }
  5793. if($link){
  5794. if($link == '#'){
  5795. icl_pop_info($alt, ICL_PLUGIN_URL . '/res/img/' .$img, array('icon_size' => 16, 'but_style'=>array('icl_pop_info_but_noabs')));
  5796. }else{
  5797. echo '<a href="'.$link.'" title="'.$alt.'">';
  5798. echo '<img style="padding:1px;margin:2px;" border="0" src="'.ICL_PLUGIN_URL . '/res/img/' .$img.'" alt="'.$alt.'" width="16" height="16" />';
  5799. echo '</a>';
  5800. }
  5801. }
  5802. }
  5803. }
  5804. function __set_posts_management_column_width(){
  5805. $w = 22 * count($this->get_active_languages());
  5806. echo '<style type="text/css">.column-icl_translations{width:'.$w.'px;}.column-icl_translations img{margin:2px;}</style>';
  5807. }
  5808. function display_wpml_footer(){
  5809. if($this->settings['promote_wpml']){
  5810. $wpml_in_other_langs = array('es','de','ja','zh-hans');
  5811. $cl = in_array(ICL_LANGUAGE_CODE, $wpml_in_other_langs) ? ICL_LANGUAGE_CODE . '/' : '';
  5812. $wpml_in_other_langs_icl = array('es','fr','de');
  5813. $cl_icl = in_array(ICL_LANGUAGE_CODE, $wpml_in_other_langs_icl) ? ICL_LANGUAGE_CODE . '/' : '';
  5814. $nofollow_wpml = is_home() ? '' : ' rel="nofollow"';
  5815. if(in_array(ICL_LANGUAGE_CODE, array('ja', 'zh-hans', 'zh-hant', 'ko'))){
  5816. // parameters order is set according to teh translation
  5817. echo '<p id="wpml_credit_footer">' .
  5818. sprintf(__('<a href="%s"%s>Multilingual WordPress</a> by <a href="%s" rel="nofollow">ICanLocalize</a>', 'sitepress'),
  5819. 'http://www.icanlocalize.com/site/'.$cl_icl, 'http://wpml.org/'.$cl, $nofollow_wpml) . '</p>';
  5820. }else{
  5821. echo '<p id="wpml_credit_footer">' .
  5822. sprintf(__('<a href="%s"%s>Multilingual WordPress</a> by <a href="%s" rel="nofollow">ICanLocalize</a>', 'sitepress'),
  5823. 'http://wpml.org/'.$cl, $nofollow_wpml, 'http://www.icanlocalize.com/site/'.$cl_icl) . '</p>';
  5824. }
  5825. }
  5826. }
  5827. function xmlrpc_methods($methods){
  5828. $methods['icanlocalize.get_languages_list'] = array($this, 'xmlrpc_get_languages_list');
  5829. return $methods;
  5830. }
  5831. function xmlrpc_call_actions($action){
  5832. global $HTTP_RAW_POST_DATA, $wpdb;
  5833. $params = icl_xml2array($HTTP_RAW_POST_DATA);
  5834. switch($action){
  5835. case 'wp.getPage':
  5836. case 'blogger.getPost': // yet this doesn't return custom fields
  5837. if(isset($params['methodCall']['params']['param'][1]['value']['int']['value'])){
  5838. $page_id = $params['methodCall']['params']['param'][1]['value']['int']['value'];
  5839. $lang_details = $this->get_element_language_details($page_id, 'post_post');
  5840. update_post_meta($page_id, '_wpml_language', $lang_details->language_code);
  5841. update_post_meta($page_id, '_wpml_trid', $lang_details->trid);
  5842. $active_languages = $this->get_active_languages();
  5843. $res = $this->get_element_translations($lang_details->trid);
  5844. $translations = array();
  5845. foreach($active_languages as $k=>$v){
  5846. if($page_id != $res[$k]->element_id){
  5847. $translations[$k] = isset($res[$k]->element_id) ? $res[$k]->element_id : 0;
  5848. }
  5849. }
  5850. update_post_meta($page_id, '_wpml_translations', json_encode($translations));
  5851. }
  5852. break;
  5853. case 'metaWeblog.getPost':
  5854. if(isset($params['methodCall']['params']['param'][0]['value']['int']['value'])){
  5855. $page_id = $params['methodCall']['params']['param'][0]['value']['int']['value'];
  5856. $lang_details = $this->get_element_language_details($page_id, 'post_post');
  5857. update_post_meta($page_id, '_wpml_language', $lang_details->language_code);
  5858. update_post_meta($page_id, '_wpml_trid', $lang_details->trid);
  5859. $active_languages = $this->get_active_languages();
  5860. $res = $this->get_element_translations($lang_details->trid);
  5861. $translations = array();
  5862. foreach($active_languages as $k=>$v){
  5863. if($page_id != $res[$k]->element_id){
  5864. $translations[$k] = isset($res[$k]->element_id) ? $res[$k]->element_id : 0;
  5865. }
  5866. }
  5867. update_post_meta($page_id, '_wpml_translations', json_encode($translations));
  5868. }
  5869. break;
  5870. case 'metaWeblog.getRecentPosts':
  5871. $num_posts = intval($params['methodCall']['params']['param'][3]['value']['int']['value']);
  5872. if($num_posts){
  5873. $posts = get_posts('suppress_filters=false&numberposts='.$num_posts);
  5874. foreach($posts as $p){
  5875. $lang_details = $this->get_element_language_details($p->ID, 'post_post');
  5876. update_post_meta($p->ID, '_wpml_language', $lang_details->language_code);
  5877. update_post_meta($p->ID, '_wpml_trid', $lang_details->trid);
  5878. $active_languages = $this->get_active_languages();
  5879. $res = $this->get_element_translations($lang_details->trid);
  5880. $translations = array();
  5881. foreach($active_languages as $k=>$v){
  5882. if($p->ID != $res[$k]->element_id){
  5883. $translations[$k] = isset($res[$k]->element_id) ? $res[$k]->element_id : 0;
  5884. }
  5885. }
  5886. update_post_meta($p->ID, '_wpml_translations', json_encode($translations));
  5887. }
  5888. }
  5889. break;
  5890. case 'metaWeblog.newPost':
  5891. $custom_fields = false;
  5892. if(is_array($params['methodCall']['params']['param'][3]['value']['struct']['member'])){
  5893. foreach($params['methodCall']['params']['param'][3]['value']['struct']['member'] as $m){
  5894. if($m['name']['value'] == 'custom_fields'){
  5895. $custom_fields_raw = $m['value']['array']['data']['value'];
  5896. break;
  5897. }
  5898. }
  5899. }
  5900. if(!empty($custom_fields_raw)){
  5901. foreach($custom_fields_raw as $cf){
  5902. $key = $value = null;
  5903. foreach($cf['struct']['member'] as $m){
  5904. if($m['name']['value'] == 'key') $key = $m['value']['string']['value'];
  5905. elseif($m['name']['value'] == 'value') $value = $m['value']['string']['value'];
  5906. }
  5907. if($key !== null && $value !== null) $custom_fields[$key] = $value;
  5908. }
  5909. }
  5910. if(is_array($custom_fields) && isset($custom_fields['_wpml_language']) && isset($custom_fields['_wpml_trid'])){
  5911. $icl_post_language = $custom_fields['_wpml_language'];
  5912. $icl_trid = $custom_fields['_wpml_trid'];
  5913. $post_type = $params['methodCall']['params']['param'][3]['value']['struct']['member'][2]['value']['string']['value'];
  5914. if(!$wpdb->get_var("SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE element_type='post_{$post_type}' AND trid={$icl_trid} AND language_code='{$icl_post_language}'")){
  5915. $_POST['icl_post_language'] = $icl_post_language;
  5916. $_POST['icl_trid'] = $icl_trid;
  5917. }else{
  5918. $IXR_Error = new IXR_Error( 401, __('A translation for this post already exists', 'sitepress') );
  5919. echo $IXR_Error->getXml();
  5920. exit(1);
  5921. }
  5922. }
  5923. break;
  5924. case 'metaWeblog.editPost':
  5925. $post_id = $params['methodCall']['params']['param'][0]['value']['int']['value'];
  5926. if(!$post_id){
  5927. break;
  5928. }
  5929. $custom_fields = $params['methodCall']['params']['param'][3]['value']['struct']['member'][3]['value']['array']['data']['value'];
  5930. if(is_array($custom_fields)){
  5931. foreach($custom_fields as $cf){
  5932. if($cf['struct']['member'][0]['value']['string']['value'] == '_wpml_language'){
  5933. $icl_post_language = $cf['struct']['member'][1]['value']['string']['value'];
  5934. }elseif($cf['struct']['member'][0]['value']['string']['value'] == '_wpml_trid'){
  5935. $icl_trid = $cf['struct']['member'][1]['value']['string']['value'];
  5936. }
  5937. }
  5938. $epost_id = $wpdb->get_var("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type='post_post'
  5939. AND trid={$icl_trid} AND language_code='{$icl_post_language}'");
  5940. if($icl_trid && $icl_post_language && (!$epost_id || $epost_id == $post_id)){
  5941. $_POST['icl_post_language'] = $icl_post_language;
  5942. $_POST['icl_trid'] = $icl_trid;
  5943. }else{
  5944. $IXR_Error = new IXR_Error( 401, __('A translation in this language already exists', 'sitepress') );
  5945. echo $IXR_Error->getXml();
  5946. exit(1);
  5947. }
  5948. }
  5949. break;
  5950. }
  5951. }
  5952. function xmlrpc_get_languages_list($lang){
  5953. global $wpdb;
  5954. if(!is_null($lang)){
  5955. if(!$wpdb->get_var("SELECT code FROM {$wpdb->prefix}icl_languages WHERE code='".mysql_real_escape_string($lang)."'")){
  5956. $IXR_Error = new IXR_Error( 401, __('Invalid language code', 'sitepress') );
  5957. echo $IXR_Error->getXml();
  5958. exit(1);
  5959. }
  5960. $this->admin_language = $lang;
  5961. }
  5962. define('WP_ADMIN', true); // hack - allow to force display language
  5963. $active_languages = $this->get_active_languages(true);
  5964. return $active_languages;
  5965. }
  5966. function get_current_action_step() {
  5967. global $wpdb;
  5968. $icl_lang_status = $this->settings['icl_lang_status'];
  5969. $has_translators = false;
  5970. foreach((array)$icl_lang_status as $k => $lang){
  5971. if(!is_numeric($k)) continue;
  5972. if(!empty($lang['translators'])){
  5973. $has_translators = true;
  5974. break;
  5975. }
  5976. }
  5977. if(!$has_translators){ return 0; }
  5978. $cms_count = $wpdb->get_var("SELECT COUNT(rid) FROM {$wpdb->prefix}icl_core_status WHERE status=3");
  5979. if($cms_count > 0) {
  5980. return 4;
  5981. }
  5982. $cms_count = $wpdb->get_var("SELECT COUNT(rid) FROM {$wpdb->prefix}icl_core_status WHERE 1");
  5983. if($cms_count == 0) {
  5984. // No documents sent yet
  5985. return 1;
  5986. }
  5987. if ($this->settings['icl_balance'] <= 0) {
  5988. return 2;
  5989. }
  5990. return 3;
  5991. }
  5992. function show_action_list() {
  5993. $steps = array(__('Select translators', 'sitepress'),
  5994. __('Send documents to translation', 'sitepress'),
  5995. __('Deposit payment', 'sitepress'),
  5996. __('Translations will be returned to your site', 'sitepress'));
  5997. $current_step = $this->get_current_action_step();
  5998. if ($current_step >= sizeof($steps)) {
  5999. // everything is already setup.
  6000. if ($this->settings['last_action_step_shown']) {
  6001. return '';
  6002. } else {
  6003. $this->save_settings(array('last_action_step_shown' => 1));
  6004. }
  6005. }
  6006. $output = '
  6007. <h3>' . __('Setup check list', 'sitepress') . '</h3>
  6008. <ul id="icl_check_list">';
  6009. foreach($steps as $index => $step) {
  6010. $step_data = $step;
  6011. if ($index < $current_step || ($index == 4 && $this->settings['icl_balance'] > 0)) {
  6012. $attr = ' class="icl_tick"';
  6013. } else {
  6014. $attr = ' class="icl_next_step"';
  6015. }
  6016. if ($index == $current_step) {
  6017. $output .= '<li class="icl_info"><b>' . $step_data . '</b></li>';
  6018. } else {
  6019. $output .= '<li' . $attr. '>' . $step_data . '</li>';
  6020. }
  6021. $output .= "\n";
  6022. }
  6023. $output .= '
  6024. </ul>';
  6025. return $output;
  6026. }
  6027. function show_pro_sidebar() {
  6028. $output = '<div id="icl_sidebar" class="icl_sidebar" style="display:none">';
  6029. $action_list = $this->show_action_list();
  6030. $show_minimized = $this->settings['icl_sidebar_minimized'];
  6031. if ($action_list != '') {
  6032. $show_minimized = false;
  6033. }
  6034. if ($show_minimized) {
  6035. $output .= '<div id="icl_sidebar_full" style="display:none">';
  6036. } else {
  6037. $output .= '<div id="icl_sidebar_full">';
  6038. }
  6039. if ($action_list == '') {
  6040. $output .= '<a id="icl_sidebar_hide" href="#">hide</a>';
  6041. } else {
  6042. $output .= $action_list;
  6043. }
  6044. $output .= '<h3>' . __('Help', 'sitepress') . '</h3>';
  6045. $output .= '<div id="icl_help_links"></div>';
  6046. $output .= wp_nonce_field('icl_help_links_nonce', '_icl_nonce_hl', false, false);
  6047. $output .= '</div>';
  6048. if ($show_minimized) {
  6049. $output .= '<div id="icl_sidebar_hide_div">';
  6050. } else {
  6051. $output .= '<div id="icl_sidebar_hide_div" style="display:none">';
  6052. }
  6053. $output .= '<a id="icl_sidebar_show" href="#"><img width="16" height="16" src="' . ICL_PLUGIN_URL . '/res/img/question1.png' . '" alt="'.__('Get help','sitepress').'" title="'.__('Get help','sitepress').'" /></a>';
  6054. $output .= wp_nonce_field('icl_show_sidebar_nonce', '_icl_nonce_ss', false, false);
  6055. $output .= '</div>';
  6056. $output .= '</div>';
  6057. return $output;
  6058. }
  6059. function meta_generator_tag(){
  6060. $lids = array();
  6061. foreach($this->get_active_languages() as $l){
  6062. $lids[] = $l['id'];
  6063. }
  6064. $stt = join(",",$lids);
  6065. $stt .= ";" . intval($this->get_icl_translation_enabled());
  6066. printf('<meta name="generator" content="WPML ver:%s stt:%s" />' . PHP_EOL, ICL_SITEPRESS_VERSION, $stt);
  6067. }
  6068. function set_language_cookie(){
  6069. if (!headers_sent()){
  6070. if(preg_match('@\.(css|js|png|jpg|gif|jpeg|bmp)@i',basename(preg_replace('@\?.*$@','',$_SERVER['REQUEST_URI']))) ||
  6071. isset($_POST['icl_ajx_action']) || isset($_POST['_ajax_nonce']) || defined('DOING_AJAX')){
  6072. return;
  6073. }
  6074. $cookie_domain = defined('COOKIE_DOMAIN') ? COOKIE_DOMAIN : $_SERVER['HTTP_HOST'];
  6075. $cookie_path = defined('COOKIEPATH') ? COOKIEPATH : '/';
  6076. setcookie('_icl_current_language', $this->get_current_language(), time()+86400, $cookie_path, $cookie_domain);
  6077. }
  6078. }
  6079. function get_language_cookie(){
  6080. if(isset($_COOKIE['_icl_current_language'])){
  6081. $lang = substr($_COOKIE['_icl_current_language'], 0, 10);
  6082. $active_languages = $this->get_active_languages();
  6083. if(!isset($active_languages[$lang])){
  6084. $lang = $this->get_default_language();
  6085. }
  6086. }else{
  6087. $lang = '';
  6088. }
  6089. return $lang;
  6090. }
  6091. // _icl_current_language will have to be replaced with _icl_current_language
  6092. function set_admin_language_cookie($lang = false){
  6093. if (!headers_sent()){
  6094. if(preg_match('@\.(css|js|png|jpg|gif|jpeg|bmp)@i',basename(preg_replace('@\?.*$@','',$_SERVER['REQUEST_URI']))) ||
  6095. isset($_POST['icl_ajx_action']) || isset($_POST['_ajax_nonce'])){
  6096. return;
  6097. }
  6098. $parts = parse_url(admin_url());
  6099. $cookie_path = $parts['path'];
  6100. if($lang === false) $lang = $this->get_current_language();
  6101. setcookie('_icl_current_admin_language', $lang, time()+7200, $cookie_path);
  6102. }
  6103. }
  6104. function get_admin_language_cookie(){
  6105. if(isset($_COOKIE['_icl_current_admin_language'])){
  6106. $lang = $_COOKIE['_icl_current_admin_language'];
  6107. $active_languages = $this->get_active_languages();
  6108. if(!isset($active_languages[$lang]) && $lang != 'all'){
  6109. $lang = $this->get_default_language();
  6110. }
  6111. }else{
  6112. $lang = '';
  6113. }
  6114. return $lang;
  6115. }
  6116. function reset_admin_language_cookie(){
  6117. $this->set_admin_language_cookie($this->get_default_language());
  6118. }
  6119. function rewrite_rules_filter($value){
  6120. foreach((array)$value as $k=>$v){
  6121. $value[$this->get_current_language().'/'.$k] = $v;
  6122. unset($value[$k]);
  6123. }
  6124. $value[$this->get_current_language() . '/?$'] = 'index.php';
  6125. return $value;
  6126. }
  6127. function is_rtl($lang = false){
  6128. if(is_admin()){
  6129. if(empty($lang)) $lang = $this->get_admin_language();
  6130. }else{
  6131. if(empty($lang)) $lang = $this->get_current_language();
  6132. }
  6133. return in_array($lang, array('ar','he','fa'));
  6134. }
  6135. function get_translatable_documents($include_not_synced = false){
  6136. global $wp_post_types;
  6137. $icl_post_types = array();
  6138. foreach($wp_post_types as $k=>$v){
  6139. if(!in_array($k, array('attachment','revision','nav_menu_item'))){
  6140. if(!$include_not_synced &&
  6141. (empty($this->settings['custom_posts_sync_option'][$k]) || $this->settings['custom_posts_sync_option'][$k] != 1) && !in_array($k, array('post','page'))) continue;
  6142. $icl_post_types[$k] = $v;
  6143. }
  6144. }
  6145. $icl_post_types = apply_filters('get_translatable_documents', $icl_post_types);
  6146. return $icl_post_types;
  6147. }
  6148. function get_translatable_taxonomies($include_not_synced = false, $object_type = 'post'){
  6149. global $wp_taxonomies;
  6150. $t_taxonomies = array();
  6151. if($include_not_synced){
  6152. if(in_array($object_type, $wp_taxonomies['post_tag']->object_type)) $t_taxonomies[] = 'post_tag';
  6153. if(in_array($object_type, $wp_taxonomies['category']->object_type)) $t_taxonomies[] = 'category';
  6154. }
  6155. foreach($wp_taxonomies as $taxonomy_name => $taxonomy){
  6156. // exceptions
  6157. if('post_format' == $taxonomy_name) continue;
  6158. if(in_array($object_type, $taxonomy->object_type) && !empty($this->settings['taxonomies_sync_option'][$taxonomy_name])){
  6159. $t_taxonomies[] = $taxonomy_name;
  6160. }
  6161. }
  6162. if(has_filter('get_translatable_taxonomies')){
  6163. $filtered = apply_filters('get_translatable_taxonomies', array('taxs'=>$t_taxonomies, 'object_type'=>$object_type));
  6164. $t_taxonomies = $filtered['taxs'];
  6165. $ot = $filtered['object_type'];
  6166. if(empty($t_taxonomies)) $t_taxonomies = array();
  6167. }
  6168. return $t_taxonomies;
  6169. }
  6170. function is_translated_taxonomy($tax){
  6171. switch($tax){
  6172. case 'category':
  6173. case 'post_tag':
  6174. $ret = true;
  6175. break;
  6176. default:
  6177. if(isset($this->settings['taxonomies_sync_option'][$tax])){
  6178. $ret = $this->settings['taxonomies_sync_option'][$tax];
  6179. }elseif(isset($this->settings['translation-management']['taxonomies_readonly_config'][$tax])
  6180. && $this->settings['translation-management']['taxonomies_readonly_config'][$tax] == 1){
  6181. $ret = true;
  6182. }else{
  6183. $ret = false;
  6184. }
  6185. }
  6186. return $ret;
  6187. }
  6188. function is_translated_post_type($type){
  6189. switch($type){
  6190. case 'post':
  6191. case 'page':
  6192. $ret = true;
  6193. break;
  6194. default:
  6195. if(isset($this->settings['custom_posts_sync_option'][$type])){
  6196. $ret = $this->settings['custom_posts_sync_option'][$type];
  6197. }elseif(isset($this->settings['translation-management']['custom_types_readonly_config'][$type])){
  6198. $ret = $this->settings['translation-management']['custom_types_readonly_config'][$type];
  6199. }else{
  6200. $ret = false;
  6201. }
  6202. }
  6203. return $ret;
  6204. }
  6205. function print_translatable_custom_content_status(){
  6206. global $wp_taxonomies;
  6207. $icl_post_types = $this->get_translatable_documents(true);
  6208. $cposts = array();
  6209. $notice = '';
  6210. foreach ($icl_post_types as $k => $v) {
  6211. if (!in_array($k, array('post', 'page'))) {
  6212. $cposts[$k] = $v;
  6213. }
  6214. }
  6215. foreach ($cposts as $k => $cpost) {
  6216. if (!isset($this->settings['custom_posts_sync_option'][$k])) {
  6217. $cposts_sync_not_set[] = $cpost->labels->name;
  6218. }
  6219. }
  6220. if (defined('WPML_TM_VERSION') && !empty($cposts_sync_not_set)) {
  6221. $notice = '<p class="updated fade">';
  6222. $notice .= sprintf(__("You haven't set your <a %s>synchronization preferences</a> for these custom posts: %s. Default value was selected.", 'sitepress'),
  6223. 'href="admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup"', '<i>' . join('</i>, <i>', $cposts_sync_not_set) . '</i>');
  6224. $notice .= '</p>';
  6225. }
  6226. $ctaxonomies = array_diff(array_keys((array) $wp_taxonomies), array('post_tag', 'category', 'nav_menu', 'link_category', 'post_format'));
  6227. foreach ($ctaxonomies as $ctax) {
  6228. if (!isset($this->settings['taxonomies_sync_option'][$ctax])) {
  6229. $tax_sync_not_set[] = $wp_taxonomies[$ctax]->label;
  6230. }
  6231. }
  6232. if (defined('WPML_TM_VERSION') && !empty($tax_sync_not_set)) {
  6233. $notice .= '<p class="updated">';
  6234. $notice .= sprintf(__("You haven't set your <a %s>synchronization preferences</a> for these taxonomies: %s. Default value was selected.", 'sitepress'),
  6235. 'href="admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup"', '<i>' . join('</i>, <i>', $tax_sync_not_set) . '</i>');
  6236. $notice .= '</p>';
  6237. }
  6238. echo $notice;
  6239. }
  6240. function dashboard_widget_setup(){
  6241. if (current_user_can('manage_options')) {
  6242. $dashboard_widgets_order = (array)get_user_option( "meta-box-order_dashboard" );
  6243. $icl_dashboard_widget_id = 'icl_dashboard_widget';
  6244. $all_widgets = array();
  6245. foreach($dashboard_widgets_order as $k=>$v){
  6246. $all_widgets = array_merge($all_widgets, explode(',', $v));
  6247. }
  6248. if(!in_array($icl_dashboard_widget_id, $all_widgets)){
  6249. $install = true;
  6250. }else{$install = false;}
  6251. wp_add_dashboard_widget($icl_dashboard_widget_id, sprintf(__('Multi-language | WPML %s', 'sitepress'),ICL_SITEPRESS_VERSION), array($this, 'dashboard_widget'), null);
  6252. if($install){
  6253. $dashboard_widgets_order['side'] = $icl_dashboard_widget_id . ',' . @strval($dashboard_widgets_order['side']);
  6254. $user = wp_get_current_user();
  6255. update_user_option($user->ID, 'meta-box-order_dashboard', $dashboard_widgets_order, true);
  6256. }
  6257. }
  6258. }
  6259. function dashboard_widget(){
  6260. do_action('icl_dashboard_widget_notices');
  6261. include_once ICL_PLUGIN_PATH . '/menu/dashboard-widget.php';
  6262. }
  6263. function verify_post_translations($post_type){
  6264. global $wpdb;
  6265. $post_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type='{$post_type}' AND post_status <> 'auto-draft'");
  6266. if(!empty($post_ids)){
  6267. foreach($post_ids as $id){
  6268. $translation_id = $wpdb->get_var("SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE element_id='{$id}' AND element_type='post_{$post_type}'");
  6269. if(!$translation_id){
  6270. $this->set_element_language_details($id, 'post_' . $post_type , false, $this->get_default_language());
  6271. }
  6272. }
  6273. }
  6274. }
  6275. function verify_taxonomy_translations($taxonomy){
  6276. global $wpdb;
  6277. $element_ids = $wpdb->get_col("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE taxonomy='{$taxonomy}'");
  6278. if(!empty($element_ids)){
  6279. foreach($element_ids as $id){
  6280. $translation_id = $wpdb->get_var("SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE element_id='{$id}' AND element_type='tax_{$taxonomy}'");
  6281. if(!$translation_id){
  6282. $this->set_element_language_details($id, 'tax_' . $taxonomy , false, $this->get_default_language());
  6283. }
  6284. }
  6285. }
  6286. }
  6287. function copy_from_original(){
  6288. global $wpdb;
  6289. $show = false;
  6290. $disabled = '';
  6291. if(isset($_GET['source_lang']) && isset($_GET['trid'])){
  6292. $source_lang = $_GET['source_lang'];
  6293. $trid = intval($_GET['trid']);
  6294. $_lang_details = $this->get_language_details($source_lang);
  6295. $source_lang_name = $_lang_details['display_name'];
  6296. $show = true;
  6297. }elseif(isset($_GET['post']) && isset($_GET['lang']) && $_GET['lang'] != $this->get_default_language()){
  6298. global $post;
  6299. if(trim($post->post_content)){
  6300. $disabled = ' disabled="disabled"';
  6301. }
  6302. $trid = $this->get_element_trid($post->ID, 'post_'. $post->post_type);
  6303. $source_lang = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE source_language_code IS NULL AND trid=%d", $trid));
  6304. $_lang_details = $this->get_language_details($source_lang);
  6305. $source_lang_name = $_lang_details['display_name'];
  6306. $show = true;
  6307. }
  6308. if($show){
  6309. wp_nonce_field('copy_from_original_nonce', '_icl_nonce_cfo_' . $trid);
  6310. echo '<input id="icl_cfo" class="button-secondary" style="float:left" type="button" value="' . sprintf(__('Copy content from %s', 'sitepress'), $source_lang_name) .'"
  6311. onclick="icl_copy_from_original(\''.esc_js($source_lang).'\', \''.esc_js($trid).'\')"'.$disabled.'/>';
  6312. icl_pop_info(__("This operation copies the content from the original language onto this translation. It's meant for when you want to start with the original content, but keep translating in this language. This button is only enabled when there's no content in the editor.", 'sitepress'), 'question');
  6313. echo '<br clear="all" />';
  6314. }
  6315. }
  6316. function wp_upgrade_locale($locale){
  6317. if(defined('WPLANG') && WPLANG){
  6318. $locale = WPLANG;
  6319. }else{
  6320. $locale = ICL_WP_UPDATE_LOCALE;
  6321. }
  6322. return $locale;
  6323. }
  6324. function admin_language_switcher(){
  6325. global $pagenow, $wpdb;
  6326. $all_langs_enabled = true;
  6327. $current_page = basename($_SERVER['SCRIPT_NAME']);
  6328. // individual translations
  6329. $is_post = false;
  6330. $is_tax = false;
  6331. $is_menu = false;
  6332. switch($pagenow){
  6333. case 'post.php':
  6334. $is_post = true;
  6335. $all_langs_enabled = false;
  6336. $post_id = @intval($_GET['post']);
  6337. $post = get_post($post_id);
  6338. $trid = $this->get_element_trid($post_id, 'post_' . $post->post_type);
  6339. $translations = $this->get_element_translations($trid, 'post_' . $post->post_type, true);
  6340. break;
  6341. case 'post-new.php':
  6342. $all_langs_enabled = false;
  6343. if(isset($_GET['trid'])){
  6344. $trid = intval($_GET['trid']);
  6345. $post_type = isset($_GET['post_type']) ? $_GET['post_type'] : 'post';
  6346. $translations = $this->get_element_translations($trid, 'post_' . $post_type, true);
  6347. $is_post = true;
  6348. }
  6349. break;
  6350. case 'edit-tags.php':
  6351. $is_tax = true;
  6352. if(isset($_GET['action']) && $_GET['action']=='edit'){
  6353. $all_langs_enabled = false;
  6354. }
  6355. $term_id = @intval($_GET['tag_ID']);
  6356. $taxonomy = $_GET['taxonomy'];
  6357. $term_tax_id = $wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE taxonomy=%s AND term_id=%d", $taxonomy, $term_id));
  6358. $trid = $this->get_element_trid($term_tax_id, 'tax_' . $taxonomy);
  6359. $translations = $this->get_element_translations($trid, 'tax_' . $taxonomy, true);
  6360. break;
  6361. case 'nav-menus.php':
  6362. $is_menu = true;
  6363. if(isset($_GET['menu']) && $_GET['menu']){
  6364. $menu_id = $_GET['menu'];
  6365. $trid = $trid = $this->get_element_trid($menu_id, 'tax_nav_menu');
  6366. $translations = $this->get_element_translations($trid, 'tax_nav_menu', true);
  6367. }
  6368. $all_langs_enabled = false;
  6369. break;
  6370. }
  6371. foreach($this->get_active_languages() as $lang){
  6372. $current_page_lang = $current_page;
  6373. parse_str($_SERVER['QUERY_STRING'], $query_vars);
  6374. unset($query_vars['lang'], $query_vars['admin_bar']);
  6375. // individual translations
  6376. if($is_post){
  6377. if(isset($translations[$lang['code']]) && isset($translations[$lang['code']]->element_id)){
  6378. $query_vars['post'] = $translations[$lang['code']]->element_id;
  6379. unset($query_vars['source_lang']);
  6380. $current_page_lang = 'post.php';
  6381. $query_vars['action'] = 'edit';
  6382. }else{
  6383. $current_page_lang = 'post-new.php';
  6384. if(isset($post)){
  6385. $query_vars['post_type'] = $post->post_type;
  6386. $query_vars['source_lang'] = $this->get_current_language();
  6387. }else{
  6388. $query_vars['post_type'] = $post_type;
  6389. }
  6390. $query_vars['trid'] = $trid;
  6391. unset($query_vars['post'], $query_vars['action']);
  6392. }
  6393. }elseif($is_tax){
  6394. if(isset($translations[$lang['code']]) && isset($translations[$lang['code']]->element_id)){
  6395. $query_vars['tag_ID'] = $translations[$lang['code']]->element_id;
  6396. }else{
  6397. $query_vars['trid'] = $trid;
  6398. $query_vars['source_lang'] = $this->get_current_language();
  6399. unset($query_vars['tag_ID'], $query_vars['action']);
  6400. }
  6401. }elseif($is_menu){
  6402. if(!empty($menu_id)){
  6403. if(isset($translations[$lang['code']]->element_id)){
  6404. $query_vars['menu'] = $translations[$lang['code']]->element_id;
  6405. }else{
  6406. $query_vars['menu'] = 0;
  6407. $query_vars['trid'] = $trid;
  6408. $query_vars['action'] = 'edit';
  6409. }
  6410. }
  6411. }
  6412. $query_string = http_build_query($query_vars);
  6413. $query = '?';
  6414. if(!empty($query_string)){
  6415. $query .= $query_string . '&';
  6416. }
  6417. $query .= 'lang=' . $lang['code']; // the default language need to specified explictly yoo in order to set the lang cookie
  6418. $linkurl = admin_url($current_page_lang . $query);
  6419. $flag = $this->get_flag($lang['code']);
  6420. if($flag->from_template){
  6421. $wp_upload_dir = wp_upload_dir();
  6422. $flag_url = $wp_upload_dir['baseurl'] . '/flags/' . $flag->flag;
  6423. }else{
  6424. $flag_url = ICL_PLUGIN_URL . '/res/flags/'.$flag->flag;
  6425. }
  6426. $langlinks[$lang['code']] = array(
  6427. 'url' => $linkurl . '&admin_bar=1',
  6428. 'current' => $lang['code'] == $this->get_current_language(),
  6429. 'anchor' => $lang['display_name'],
  6430. 'flag' => '<img class="admin_iclflag" src="'.$flag_url.'" alt="'.$lang['code'].'" width="18" height="12" />'
  6431. );
  6432. }
  6433. if($all_langs_enabled){
  6434. $query = '?';
  6435. if(!empty($query_string)){
  6436. $query .= $query_string . '&';
  6437. }
  6438. $query .= 'lang=all';
  6439. $linkurl = admin_url(basename($_SERVER['SCRIPT_NAME']) . $query);
  6440. $langlinks['all'] = array(
  6441. 'url' => $linkurl,
  6442. 'current' => 'all' == $this->get_current_language(),
  6443. 'anchor' => __('All languages', 'sitepress'),
  6444. 'flag' => '<img class="admin_iclflag" src="'.ICL_PLUGIN_URL.'/res/img/icon16.png" alt="all" width="16" height="16" />'
  6445. );
  6446. }else{
  6447. // set the default language as current
  6448. if('all' == $this->get_current_language()){
  6449. $langlinks[$this->get_default_language()]['current'] = true;
  6450. }
  6451. }
  6452. include ICL_PLUGIN_PATH . '/menu/admin-language-switcher.php';
  6453. }
  6454. function admin_notices($message, $class="updated"){
  6455. static $hook_added = 0;
  6456. $this->_admin_notices[] = array('class'=>$class, 'message'=>$message);
  6457. if(!$hook_added)
  6458. add_action('admin_notices', array($this, '_admin_notices_hook'));
  6459. $hook_added = 1;
  6460. }
  6461. function _admin_notices_hook(){
  6462. if(!empty($this->_admin_notices))
  6463. foreach($this->_admin_notices as $n){
  6464. echo '<div class="'.$n['class'].'">';
  6465. echo '<p>' . $n['message'] . '</p>';
  6466. echo '</div>';
  6467. }
  6468. }
  6469. function save_user_preferences(){
  6470. update_user_meta(get_current_user_id(), '_icl_preferences', $this->user_preferences);
  6471. }
  6472. function get_user_preferences(){
  6473. if(empty($this->user_preferences)){
  6474. $this->user_preferences = get_user_meta(get_current_user_id(), '_icl_preferences', true);
  6475. }
  6476. return $this->user_preferences;
  6477. }
  6478. function setup_canonical_urls(){
  6479. global $wp_the_query;
  6480. // Yoast Exception
  6481. global $wpseo_front;
  6482. if(isset($wpseo_front) && has_filter('wp_head', array($wpseo_front, 'head'))) return;
  6483. if ( is_singular() ){
  6484. $id = $wp_the_query->get_queried_object_id();
  6485. $master_post_id = get_post_meta($id, '_icl_lang_duplicate_of', true);
  6486. if($id && $master_post_id != $id){
  6487. remove_action('wp_head', 'rel_canonical');
  6488. add_action('wp_head', array($this, 'rel_canonical'));
  6489. }
  6490. }
  6491. }
  6492. function rel_canonical() {
  6493. global $wp_the_query;
  6494. $id = $wp_the_query->get_queried_object_id();
  6495. if($master_post_id = get_post_meta($id, '_icl_lang_duplicate_of', true)){
  6496. $link = get_permalink( $master_post_id );
  6497. echo "<link rel='canonical' href='$link' />\n";
  6498. }
  6499. }
  6500. function head_langs(){
  6501. $languages = $this->get_ls_languages(array('skip_missing' => true));
  6502. foreach($languages as $code => $lang){
  6503. if($code != $this->get_current_language()){
  6504. printf('<link rel="alternate" hreflang="%s" href="%s" />' . PHP_EOL, $this->get_locale($code), html_entity_decode($lang['url']));
  6505. }
  6506. }
  6507. }
  6508. function allowed_redirect_hosts($hosts){
  6509. if($this->settings['language_negotiation_type']==2){
  6510. foreach($this->settings['language_domains'] as $code => $url){
  6511. if(!empty($this->active_languages[$code])){
  6512. $parts = parse_url($url);
  6513. if(!in_array($parts['host'], $hosts)){
  6514. $hosts[] = $parts['host'];
  6515. }
  6516. }
  6517. }
  6518. }
  6519. return $hosts;
  6520. }
  6521. function icl_nonces(){
  6522. //messages
  6523. wp_nonce_field('icl_messages_nonce', '_icl_nonce_m');
  6524. wp_nonce_field('icl_show_reminders_nonce', '_icl_nonce_sr');
  6525. }
  6526. }