PageRenderTime 156ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 3ms

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

https://bitbucket.org/acipriani/madeinapulia.com
PHP | 11454 lines | 8995 code | 1677 blank | 782 comment | 2646 complexity | 1da29a2c6e3b1891894f9ae7200fde4a MD5 | raw file
Possible License(s): GPL-3.0, MIT, BSD-3-Clause, LGPL-2.1, GPL-2.0, Apache-2.0
  1. <?php
  2. /**
  3. * Main SitePress Class
  4. *
  5. * @package wpml-core
  6. */
  7. class SitePress
  8. {
  9. private $settings;
  10. private $active_languages = array();
  11. private $this_lang;
  12. private $wp_query;
  13. private $admin_language = null;
  14. private $user_preferences = array();
  15. private $current_user;
  16. public $footer_preview = false;
  17. public $queries = array();
  18. /**
  19. * @var icl_cache
  20. */
  21. public $icl_translations_cache;
  22. /**
  23. * @var icl_cache
  24. */
  25. public $icl_locale_cache;
  26. /**
  27. * @var icl_cache
  28. */
  29. public $icl_flag_cache;
  30. /**
  31. * @var icl_cache
  32. */
  33. public $icl_language_name_cache;
  34. /**
  35. * @var icl_cache
  36. */
  37. public $icl_term_taxonomy_cache;
  38. function __construct()
  39. {
  40. do_action('wpml_before_startup');
  41. global $wpdb, $pagenow;
  42. $this->settings = get_option( 'icl_sitepress_settings' );
  43. //@tODO: To remove in WPML 3.5
  44. //@since 3.1
  45. if(is_admin() && !$this->get_setting('icl_capabilities_verified')) {
  46. icl_enable_capabilities();
  47. $this->settings = get_option( 'icl_sitepress_settings' );
  48. }
  49. // set up current user early
  50. // no authentication
  51. if ( defined( 'LOGGED_IN_COOKIE' ) && isset( $_COOKIE[ LOGGED_IN_COOKIE ] ) ) {
  52. list( $username ) = explode( '|', $_COOKIE[ LOGGED_IN_COOKIE ] );
  53. $user_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->users} WHERE user_login = %s", array($username) ) );
  54. } else {
  55. $user_id = 0;
  56. }
  57. $this->current_user = new WP_User( $user_id );
  58. if ( is_null( $pagenow ) && is_multisite() ) {
  59. include ICL_PLUGIN_PATH . '/inc/hacks/vars-php-multisite.php';
  60. }
  61. if ( false != $this->settings ) {
  62. $this->verify_settings();
  63. }
  64. if ( isset( $_GET[ 'icl_action' ] ) ) {
  65. require_once ABSPATH . WPINC . '/pluggable.php';
  66. if ( $_GET[ 'icl_action' ] == 'reminder_popup' ) {
  67. add_action( 'init', array( $this, 'reminders_popup' ) );
  68. } elseif ( $_GET[ 'icl_action' ] == 'dismiss_help' ) {
  69. $this->settings[ 'dont_show_help_admin_notice' ] = true;
  70. $this->save_settings();
  71. }
  72. }
  73. if ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == ICL_PLUGIN_FOLDER . '/menu/troubleshooting.php' && isset( $_GET[ 'debug_action' ] ) ) {
  74. ob_start();
  75. }
  76. if ( isset( $_REQUEST[ 'icl_ajx_action' ] ) ) {
  77. add_action( 'init', array( $this, 'ajax_setup' ), 15 );
  78. }
  79. add_action( 'admin_footer', array( $this, 'icl_nonces' ) );
  80. // Process post requests
  81. if ( !empty( $_POST ) ) {
  82. add_action( 'init', array( $this, 'process_forms' ) );
  83. }
  84. add_action( 'plugins_loaded', array( $this, 'initialize_cache' ), 0 );
  85. add_action( 'plugins_loaded', array( $this, 'init' ), 1 );
  86. add_action( 'init', array( $this, 'on_wp_init' ), 1 );
  87. add_action( 'admin_print_scripts', array( $this, 'js_scripts_setup' ) );
  88. add_action( 'admin_print_styles', array( $this, 'css_setup' ) );
  89. // Administration menus
  90. add_action( 'admin_menu', array( $this, 'administration_menu' ) );
  91. add_action( 'admin_menu', array( $this, 'administration_menu2' ), 30 );
  92. add_action( 'init', array( $this, 'plugin_localization' ) );
  93. //add_filter('tag_template', array($this, 'load_taxonomy_template'));
  94. if ( $this->settings[ 'existing_content_language_verified' ] && ( $this->settings[ 'setup_complete' ] || ( !empty($_GET[ 'page' ]) && $this->settings['setup_wizard_step']==3 && $_GET[ 'page' ] == ICL_PLUGIN_FOLDER . '/menu/languages.php' ) ) ) {
  95. // Post/page language box
  96. if ( $pagenow == 'post.php' || $pagenow == 'post-new.php' || $pagenow == 'edit.php' ) {
  97. add_action( 'admin_head', array( $this, 'post_edit_language_options' ) );
  98. }
  99. //For when it will be possible to add custom bulk actions
  100. //add_action( 'bulk_actions-edit-post', array( $this, 'bulk_actions' ) );
  101. // Post/page save actions
  102. add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
  103. add_action( 'updated_post_meta', array( $this, 'update_post_meta' ), 100, 4 );
  104. add_action( 'added_post_meta', array( $this, 'update_post_meta' ), 100, 4 );
  105. add_action( 'updated_postmeta', array( $this, 'update_post_meta' ), 100, 4 ); // ajax
  106. add_action( 'added_postmeta', array( $this, 'update_post_meta' ), 100, 4 ); // ajax
  107. add_action( 'delete_postmeta', array( $this, 'delete_post_meta' ) ); // ajax
  108. // Post/page delete actions
  109. // add_action('delete_post', array($this,'delete_post_actions'));
  110. add_action( 'before_delete_post', array( $this, 'before_delete_post_actions' ) );
  111. add_action( 'deleted_post', array( $this, 'deleted_post_actions' ) );
  112. add_action( 'wp_trash_post', array( $this, 'trash_post_actions' ) );
  113. add_action( 'untrashed_post', array( $this, 'untrashed_post_actions' ) );
  114. add_filter( 'posts_join', array( $this, 'posts_join_filter' ), 10, 2 );
  115. add_filter( 'posts_where', array( $this, 'posts_where_filter' ), 10, 2 );
  116. add_filter( 'comment_feed_join', array( $this, 'comment_feed_join' ) );
  117. add_filter( 'comments_clauses', array( $this, 'comments_clauses' ), 10, 2 );
  118. // Allow us to filter the Query vars before the posts query is being built and executed
  119. add_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
  120. add_action( 'loop_start', array( $this, 'loop_start' ), 10 );
  121. add_filter( 'the_posts', array( $this, 'the_posts' ), 10 );
  122. add_filter( 'get_pages', array( $this, 'get_pages' ), 100, 2 );
  123. // Filter links to the root page
  124. add_filter('page_link', array($this, 'filter_root_permalink'), 10, 2);
  125. if ( $pagenow == 'edit.php' ) {
  126. add_action( 'admin_footer', array( $this, 'language_filter' ) );
  127. add_action( 'quick_edit_custom_box', array( 'WPML_Terms_Translations', 'quick_edit_terms_removal' ), 10, 2 );
  128. }
  129. add_filter( 'get_pages', array( $this, 'exclude_other_language_pages2' ) );
  130. add_filter( 'wp_dropdown_pages', array( $this, 'wp_dropdown_pages' ) );
  131. // posts and pages links filters
  132. add_filter( 'post_link', array( $this, 'permalink_filter' ), 1, 2 );
  133. add_filter( 'post_type_link', array( $this, 'permalink_filter' ), 1, 2 );
  134. add_filter( 'page_link', array( $this, 'permalink_filter' ), 1, 2 );
  135. add_filter( 'get_comment_link', array( $this, 'get_comment_link_filter' ) );
  136. // filter the saving of terms so that the taxonomy_ids of translated terms are correctly adjusted across taxonomies
  137. add_action('created_term_translation', array( 'WPML_Terms_Translations', 'sync_ttid_action' ), 10, 3 );
  138. // filters terms by language for the term/tag-box autoselect
  139. if ( ( isset( $_GET[ 'action' ] ) && ( $_GET[ 'action' ] == 'ajax-tag-search' )
  140. || isset( $_POST[ 'action' ] ) && $_POST[ 'action' ] == 'get-tagcloud' ) ) {
  141. add_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
  142. }
  143. $this->set_term_filters_and_hooks();
  144. // The delete filter only ensures the synchronizing of delete actions beween translations of a term.
  145. add_action( 'delete_term', array( 'WPML_Terms_Translations', 'delete_term_filter' ), 1, 3 );
  146. add_filter('pre_term_slug', array( 'WPML_Terms_Translations', 'pre_term_slug_filter' ), 10, 2 );
  147. add_action( 'set_object_terms', array( 'WPML_Terms_Translations', 'set_object_terms_action' ), 10, 6 );
  148. // AJAX Actions for the post edit screen
  149. add_action( 'wp_ajax_wpml_get_post_parent_id_by_lang', array( 'WPML_Post_Edit_Ajax', 'wpml_get_post_parent_id_by_lang' ) );
  150. add_action( 'wp_ajax_wpml_get_taxonomy_terms_json', array( 'WPML_Post_Edit_Ajax', 'wpml_get_taxonomy_terms_json' ) );
  151. add_action( 'wp_ajax_wpml_add_term_to_post', array( 'WPML_Post_Edit_Ajax', 'wpml_add_term_to_post' ) );
  152. add_action( 'wp_ajax_wpml_remove_terms_from_post', array( 'WPML_Post_Edit_Ajax', 'wpml_remove_terms_from_post' ) );
  153. add_action( 'wp_ajax_wpml_switch_post_language', array( 'WPML_Post_Edit_Ajax', 'wpml_switch_post_language' ) );
  154. add_action( 'wp_ajax_wpml_before_switch_post_language', array( 'WPML_Post_Edit_Ajax', 'wpml_before_switch_post_language' ) );
  155. add_action( 'wp_ajax_wpml_set_post_edit_lang', array( 'WPML_Post_Edit_Ajax', 'wpml_set_post_edit_lang' ) );
  156. add_action( 'wp_ajax_wpml_get_translated_taxonomies', array( 'WPML_Post_Edit_Ajax', 'wpml_get_translated_taxonomies' ) );
  157. add_action( 'wp_ajax_wpml_get_translations_table_data', array( 'WPML_Post_Edit_Ajax', 'wpml_get_translations_table_data' ) );
  158. add_action( 'wp_ajax_wpml_get_post_permalink', array( 'WPML_Post_Edit_Ajax', 'wpml_get_post_permalink' ) );
  159. add_action( 'wp_ajax_wpml_get_default_lang', array( 'WPML_Post_Edit_Ajax', 'wpml_get_default_lang' ) );
  160. // Ajax Action for the updating of term names on the troubleshooting page
  161. add_action( 'wp_ajax_wpml_update_term_names_troubleshoot', array( 'WPML_Troubleshooting_Terms_Menu', 'wpml_update_term_names_troubleshoot' ) );
  162. // short circuit get default category
  163. add_filter( 'pre_option_default_category', array( $this, 'pre_option_default_category' ) );
  164. add_filter( 'update_option_default_category', array( $this, 'update_option_default_category' ), 1, 2 );
  165. add_action( 'after-category-table', array( 'WPML_Terms_Translations', 'category_display_action' ), 1, 1 );
  166. // custom hook for adding the language selector to the template
  167. add_action( 'icl_language_selector', array( $this, 'language_selector' ) );
  168. // front end js
  169. add_action( 'wp_head', array( $this, 'front_end_js' ) );
  170. add_action( 'wp_head', array( $this, 'rtl_fix' ) );
  171. add_action( 'admin_print_styles', array( $this, 'rtl_fix' ) );
  172. add_action( 'restrict_manage_posts', array( $this, 'restrict_manage_posts' ) );
  173. add_filter( 'get_edit_post_link', array( $this, 'get_edit_post_link' ), 1, 3 );
  174. // adjacent posts links
  175. add_filter( 'get_previous_post_join', array( $this, 'get_adjacent_post_join' ) );
  176. add_filter( 'get_next_post_join', array( $this, 'get_adjacent_post_join' ) );
  177. add_filter( 'get_previous_post_where', array( $this, 'get_adjacent_post_where' ) );
  178. add_filter( 'get_next_post_where', array( $this, 'get_adjacent_post_where' ) );
  179. // feeds links
  180. add_filter( 'feed_link', array( $this, 'feed_link' ) );
  181. // commenting links
  182. add_filter( 'post_comments_feed_link', array( $this, 'post_comments_feed_link' ) );
  183. add_filter( 'trackback_url', array( $this, 'trackback_url' ) );
  184. add_filter( 'user_trailingslashit', array( $this, 'user_trailingslashit' ), 1, 2 );
  185. // date based archives
  186. add_filter( 'year_link', array( $this, 'archives_link' ) );
  187. add_filter( 'month_link', array( $this, 'archives_link' ) );
  188. add_filter( 'day_link', array( $this, 'archives_link' ) );
  189. add_filter( 'getarchives_join', array( $this, 'getarchives_join' ) );
  190. add_filter( 'getarchives_where', array( $this, 'getarchives_where' ) );
  191. add_filter( 'pre_option_home', array( $this, 'pre_option_home' ) );
  192. if ( !is_admin() ) {
  193. add_filter( 'attachment_link', array( $this, 'attachment_link_filter' ), 10, 2 );
  194. }
  195. // Filter custom type archive link (since WP 3.1)
  196. add_filter( 'post_type_archive_link', array( $this, 'post_type_archive_link_filter' ), 10, 2 );
  197. add_filter( 'author_link', array( $this, 'author_link' ) );
  198. add_filter( 'wp_unique_post_slug', array( $this, 'wp_unique_post_slug' ), 100, 5 );
  199. add_filter( 'home_url', array( $this, 'home_url' ), 1, 4 );
  200. // language negotiation
  201. add_action( 'query_vars', array( $this, 'query_vars' ) );
  202. add_filter( 'language_attributes', array( $this, 'language_attributes' ) );
  203. add_action( 'locale', array( $this, 'locale' ) );
  204. if ( isset( $_GET[ '____icl_validate_domain' ] ) ) {
  205. echo '<!--' . get_home_url() . '-->';
  206. exit;
  207. }
  208. add_filter( 'pre_option_page_on_front', array( $this, 'pre_option_page_on_front' ) );
  209. add_filter( 'pre_option_page_for_posts', array( $this, 'pre_option_page_for_posts' ) );
  210. add_filter( 'option_sticky_posts', array( $this, 'option_sticky_posts' ) );
  211. add_filter( 'request', array( $this, 'request_filter' ) );
  212. add_action( 'wp_head', array( $this, 'set_wp_query' ) );
  213. add_action( 'show_user_profile', array( $this, 'show_user_options' ) );
  214. add_action( 'personal_options_update', array( $this, 'save_user_options' ) );
  215. // column with links to translations (or add translation) - low priority
  216. add_action( 'init', array( $this, 'configure_custom_column' ), 1010 ); // accommodate Types init@999
  217. if ( !is_admin() ) {
  218. add_action( 'wp_head', array( $this, 'meta_generator_tag' ) );
  219. }
  220. require_once ICL_PLUGIN_PATH . '/inc/wp-nav-menus/iclNavMenu.class.php';
  221. new iclNavMenu;
  222. if ( is_admin() || defined( 'XMLRPC_REQUEST' ) || preg_match( '#wp-comments-post\.php$#', $_SERVER[ 'REQUEST_URI' ] ) ) {
  223. global $iclTranslationManagement, $ICL_Pro_Translation;
  224. $iclTranslationManagement = new TranslationManagement;
  225. $ICL_Pro_Translation = new ICL_Pro_Translation();
  226. }
  227. add_action( 'wp_login', array( $this, 'reset_admin_language_cookie' ) );
  228. if ( $this->settings[ 'seo' ][ 'canonicalization_duplicates' ] ) {
  229. add_action( 'template_redirect', array( $this, 'setup_canonical_urls' ), 100 );
  230. }
  231. add_action( 'init', array( $this, '_taxonomy_languages_menu' ), 99 ); //allow hooking in
  232. if ( $this->settings[ 'seo' ][ 'head_langs' ] ) {
  233. add_action( 'wp_head', array( $this, 'head_langs' ) );
  234. }
  235. /**
  236. * add extra debug information
  237. */
  238. add_filter( 'icl_get_extra_debug_info', array( $this, 'add_extra_debug_info' ) );
  239. } //end if the initial language is set - existing_content_language_verified
  240. add_action( 'wp_dashboard_setup', array( $this, 'dashboard_widget_setup' ) );
  241. if ( is_admin() && $pagenow == 'index.php' ) {
  242. add_action( 'icl_dashboard_widget_notices', array( $this, 'print_translatable_custom_content_status' ) );
  243. }
  244. add_filter( 'core_version_check_locale', array( $this, 'wp_upgrade_locale' ) );
  245. if ( $pagenow == 'post.php' && isset( $_REQUEST[ 'action' ] ) && $_REQUEST[ 'action' ] == 'edit' && isset( $_GET[ 'post' ] ) ) {
  246. add_action( 'init', '_icl_trash_restore_prompt' );
  247. }
  248. add_action( 'init', array( $this, 'js_load' ), 2 ); // enqueue scripts - higher priority
  249. add_filter( 'get_pagenum_link', array( $this, 'get_pagenum_link' ) );
  250. add_action('switch_blog', array($this, 'init_settings'));
  251. add_filter('url_to_postid', array($this, 'url_to_postid'));
  252. //cron job to update WPML config index file from CDN
  253. add_action('update_wpml_config_index', array($this,'update_wpml_config_index_event'));
  254. //update WPML config files
  255. add_action('wp_ajax_update_wpml_config_index', array($this,'update_wpml_config_index_event_ajax'));
  256. add_action( 'after_switch_theme', array( $this, 'update_wpml_config_index_event' ) );
  257. add_action( 'activated_plugin', array( $this, 'update_wpml_config_index_event' ) );
  258. add_action('core_upgrade_preamble', array($this, 'update_index_screen'));
  259. add_shortcode('wpml_language_selector_widget', 'icl_language_selector');
  260. add_shortcode('wpml_language_selector_footer', 'icl_language_selector_footer');
  261. add_filter('get_search_form', array($this, 'get_search_form_filter'));
  262. add_action('plugins_loaded', array($this, 'load_dependencies'), 10000);
  263. do_action('wpml_after_startup');
  264. }
  265. function get_pagenum_link( $url ) {
  266. // fix cases like that in url:
  267. // lang=pl%2F%3Flang%3Dpl
  268. // lang=pl/?lang=pl
  269. $current_language = $this->get_current_language();
  270. $find[ ] = 'lang=' . $current_language . '%2F%3Flang%3D' . $current_language;
  271. $find[ ] = 'lang=' . $current_language . '/?lang=' . $current_language;
  272. $replace = 'lang=' . $current_language;
  273. $url = str_replace( $find, $replace, $url );
  274. // fix cases like that:
  275. // ?lang=pl/page/3/?lang=pl
  276. $pattern = '/(\?lang=' . $current_language . ')(\/page\/\d+)/';
  277. $url = preg_replace( $pattern, '$2', $url );
  278. return $url;
  279. }
  280. function init()
  281. {
  282. do_action('wpml_before_init');
  283. global $wpdb;
  284. $this->get_user_preferences();
  285. $this->set_admin_language();
  286. $default_language = $this->get_default_language();
  287. // default value for theme_localization_type OR
  288. // reset theme_localization_type if string translation was on (theme_localization_type was set to 2) and then it was deactivated
  289. if ( !isset( $this->settings[ 'theme_localization_type' ] ) || ( $this->settings[ 'theme_localization_type' ] == 1 && !defined( 'WPML_ST_VERSION' ) && !defined( 'WPML_DOING_UPGRADE' ) ) ) {
  290. global $sitepress_settings;
  291. $this->settings[ 'theme_localization_type' ] = $sitepress_settings[ 'theme_localization_type' ] = 2;
  292. }
  293. //configure callbacks for plugin menu pages
  294. if ( defined( 'WP_ADMIN' ) && isset( $_GET[ 'page' ] ) && 0 === strpos( $_GET[ 'page' ], basename( ICL_PLUGIN_PATH ) . '/' ) ) {
  295. add_action( 'icl_menu_footer', array( $this, 'menu_footer' ) );
  296. }
  297. //Run only if existing content language has been verified, and is front-end or settings are not corrupted
  298. if (!empty( $this->settings[ 'existing_content_language_verified' ] ) && (!is_admin() || SitePress::check_settings_integrity()) ) {
  299. if ( $this->settings[ 'language_negotiation_type' ] == 1 && $this->settings[ 'urls' ][ 'directory_for_default_language' ] && $this->settings[ 'urls' ][ 'show_on_root' ] == 'page' ) {
  300. include ICL_PLUGIN_PATH . '/inc/home-url-functions.php';
  301. }
  302. if ($this->settings[ 'language_negotiation_type' ] == 2) {
  303. add_filter( 'allowed_redirect_hosts', array( $this, 'allowed_redirect_hosts' ) );
  304. }
  305. if ( defined( 'WP_ADMIN' ) ) {
  306. if ( $this->settings[ 'language_negotiation_type' ] == 2 ) {
  307. //Login and Logout
  308. add_filter( 'login_url', array( $this, 'convert_url' ) );
  309. add_filter( 'logout_url', array( $this, 'convert_url' ) );
  310. add_filter( 'site_url', array( $this, 'convert_url' ) );
  311. }
  312. if (isset($_GET['post']) && is_numeric($_GET['post'])) {
  313. $post_type = get_post_type($_GET['post']);
  314. }
  315. $current_user = wp_get_current_user();
  316. if ( isset( $_GET[ 'lang' ] ) ) {
  317. $this->this_lang = rtrim( strip_tags( $_GET[ 'lang' ] ), '/' );
  318. $al = $this->get_active_languages();
  319. $al[ 'all' ] = true;
  320. if ( empty( $al[ $this->this_lang ] ) ) {
  321. $this->this_lang = $default_language;
  322. }
  323. // force default language for string translation
  324. // we also make sure it's not saved in the cookie
  325. } elseif ( isset( $_GET[ 'page' ] ) && ( ( defined( 'WPML_ST_FOLDER' ) && $_GET[ 'page' ] == WPML_ST_FOLDER . '/menu/string-translation.php' ) || ( defined( 'WPML_TM_FOLDER' ) && $_GET[ 'page' ] == WPML_TM_FOLDER . '/menu/translations-queue.php' ) )
  326. ) {
  327. $this->this_lang = $default_language;
  328. } elseif ( wpml_is_ajax() ) {
  329. $al = $this->get_active_languages();
  330. if ( isset( $_POST[ 'lang' ] ) && isset( $al[ $_POST[ 'lang' ] ] ) ) {
  331. $this->this_lang = $_POST[ 'lang' ];
  332. } else {
  333. if ($this->check_if_admin_action_from_referer()){
  334. $this->this_lang = $this->get_admin_language_cookie();
  335. } elseif(isset($_SERVER['HTTP_REFERER'])) {
  336. $this->this_lang = $this->get_language_from_url($_SERVER['HTTP_REFERER']);
  337. }
  338. }
  339. } elseif ( $lang = $this->get_admin_language_cookie() ) {
  340. $this->this_lang = $lang;
  341. } elseif ( isset($_POST['action']) && $_POST['action'] == 'editpost' && isset($_POST['icl_post_language'])) {
  342. $this->this_lang = $_POST['icl_post_language'];
  343. } elseif ( isset($_GET['post']) && is_numeric($_GET['post']) && isset($post_type) && $this->is_translated_post_type($post_type)) {
  344. $this->this_lang = $this->get_language_for_element($_GET['post'], 'post_' . $post_type);
  345. } elseif(isset($current_user->data)) {
  346. $lang = $this->get_user_admin_language( $current_user->data->ID );
  347. $this->this_lang = $lang ? $lang : $default_language;
  348. }
  349. $update_admin_language_cookie = false;
  350. $update_admin_language_cookie |= is_admin() && isset($_GET['lang']) && ( $this->get_current_language() != $this->get_admin_language_cookie() );
  351. $update_admin_language_cookie |= isset( $_GET[ 'admin_bar' ] ) && ( $_GET[ 'admin_bar' ] == 1 ) && !isset( $_GET[ 'page' ] );
  352. $update_admin_language_cookie |= !defined( 'WPML_ST_FOLDER' ) || ( isset($_GET[ 'page' ]) && $_GET[ 'page' ] != WPML_ST_FOLDER . '/menu/string-translation.php' );
  353. $update_admin_language_cookie |= !$this->get_admin_language_cookie();
  354. if ( $update_admin_language_cookie ) {
  355. $this->set_admin_language_cookie();
  356. }
  357. } else {
  358. $al = $this->get_active_languages();
  359. foreach ( $al as $l ) {
  360. $active_languages[ ] = $l[ 'code' ];
  361. }
  362. $active_languages[ ] = 'all';
  363. $s = isset( $_SERVER[ 'HTTPS' ] ) && $_SERVER[ 'HTTPS' ] == 'on' ? 's' : '';
  364. $home = get_home_url();
  365. if ( $s ) {
  366. $home = preg_replace( '#^http://#', 'https://', $home );
  367. }
  368. $url_parts = parse_url( $home );
  369. $non_default_port = ( isset( $url_parts[ 'port' ] ) && $url_parts[ 'port' ] != 80 ) ? ':' . $url_parts[ 'port' ] : '';
  370. $request = 'http' . $s . '://' . $this->get_server_host_name() . $_SERVER[ 'REQUEST_URI' ];
  371. $blog_path = ! empty( $url_parts[ 'path' ] ) ? $url_parts[ 'path' ] : '';
  372. switch ( $this->settings[ 'language_negotiation_type' ] ) {
  373. case 1:
  374. $path = str_replace( $home, '', $request );
  375. $parts = explode( '?', $path );
  376. $path = $parts[ 0 ];
  377. $exp = explode( '/', trim( $path, '/' ) );
  378. $language_part = $exp[ 0 ];
  379. if ( in_array( $language_part, $active_languages ) ) {
  380. $this->this_lang = $exp[ 0 ];
  381. // before hijacking the SERVER[REQUEST_URI]
  382. // override the canonical_redirect action
  383. // keep a copy of the original request uri
  384. remove_action( 'template_redirect', 'redirect_canonical' );
  385. global $_icl_server_request_uri;
  386. $_icl_server_request_uri = $_SERVER[ 'REQUEST_URI' ];
  387. add_action( 'template_redirect', array($this,'icl_redirect_canonical_wrapper'), 0 );
  388. //deal with situations when template files need to be called directly
  389. add_action( 'template_redirect', array( $this, '_allow_calling_template_file_directly' ) );
  390. //$_SERVER['REQUEST_URI'] = preg_replace('@^'. $blog_path . '/' . $this->this_lang.'@i', $blog_path ,$_SERVER['REQUEST_URI']);
  391. // Check for special case of www.example.com/fr where the / is missing on the end
  392. $parts = parse_url( $_SERVER[ 'REQUEST_URI' ] );
  393. if ( strlen( $parts[ 'path' ] ) == 0 ) {
  394. $_SERVER[ 'REQUEST_URI' ] = '/' . $_SERVER[ 'REQUEST_URI' ];
  395. }
  396. } else {
  397. $this->this_lang = $default_language;
  398. }
  399. /* If we access the root url via a non root slug/parameter combination,
  400. * we redirect accordingly.
  401. */
  402. if ( $this->settings[ 'language_negotiation_type' ] == 1 && $this->settings[ 'urls' ][ 'directory_for_default_language' ] && $this->settings[ 'urls' ][ 'show_on_root' ] == 'page' ) {
  403. $filtered_root_url = $this->filter_root_permalink( wpml_strip_subdir_from_url( site_url() ) . $_SERVER[ 'REQUEST_URI' ] );
  404. if ( $filtered_root_url != wpml_strip_subdir_from_url( site_url() ) . $_SERVER[ 'REQUEST_URI' ] ) {
  405. wp_redirect( $filtered_root_url, 302 );
  406. exit();
  407. }
  408. }
  409. if ( $this->is_root_page() ) {
  410. if ( $this->settings[ 'urls' ][ 'show_on_root' ] == 'html_file' ) {
  411. // html file
  412. if ( false === strpos( $this->settings[ 'urls' ][ 'root_html_file_path' ], '/' ) ) {
  413. $html_file = ABSPATH . $this->settings[ 'urls' ][ 'root_html_file_path' ];
  414. } else {
  415. $html_file = $this->settings[ 'urls' ][ 'root_html_file_path' ];
  416. }
  417. /** @noinspection PhpIncludeInspection */
  418. include $html_file;
  419. exit;
  420. } else {
  421. wpml_home_url_setup_root_page();
  422. }
  423. }
  424. break;
  425. case 2:
  426. $this->this_lang = $default_language;
  427. foreach( $this->settings[ 'language_domains' ] as $language_code => $domain ){
  428. if( rtrim( $this->get_server_host_name() . $blog_path, '/' ) == rtrim( preg_replace( '@^https?://@', '', $domain ), '/' ) ){
  429. $this->this_lang = $language_code;
  430. break;
  431. }
  432. }
  433. if ( defined( 'ICL_USE_MULTIPLE_DOMAIN_LOGIN' ) && ICL_USE_MULTIPLE_DOMAIN_LOGIN ) {
  434. include ICL_PLUGIN_PATH . '/modules/multiple-domains-login.php';
  435. }
  436. add_filter( 'site_url', array( $this, 'convert_url' ) );
  437. break;
  438. case 3:
  439. default:
  440. if ( isset( $_GET[ 'lang' ] ) ) {
  441. $this->this_lang = preg_replace( "/[^0-9a-zA-Z-]/i", '', strip_tags( $_GET[ 'lang' ] ) );
  442. // set the language based on the content id - for short links
  443. } elseif ( isset( $_GET[ 'page_id' ] ) ) {
  444. $language_code_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_type='post_page' AND element_id=%d", $_GET[ 'page_id' ] );
  445. $this->this_lang = $wpdb->get_var( $language_code_prepared );
  446. } elseif ( isset( $_GET[ 'p' ] ) ) {
  447. $post_type_prepared = $wpdb->prepare( "SELECT post_type FROM {$wpdb->posts} WHERE ID=%d", $_GET[ 'p' ] );
  448. $post_type = $wpdb->get_var( $post_type_prepared );
  449. $language_code_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_type=%s AND element_id=%d", 'post_' . $post_type, $_GET[ 'p' ] );
  450. $this->this_lang = $wpdb->get_var( $language_code_prepared );
  451. } elseif ( isset( $_GET[ 'cat_ID' ] ) ) {
  452. $cat_tax_id_prepared = $wpdb->prepare( "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", $_GET[ 'cat_ID' ], 'category' );
  453. $cat_tax_id = $wpdb->get_var( $cat_tax_id_prepared );
  454. $language_code_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_type='tax_category' AND element_id=%d", $cat_tax_id );
  455. $this->this_lang = $wpdb->get_var( $language_code_prepared );
  456. } elseif ( isset( $_GET[ 'tag' ] ) ) {
  457. $tag_tax_id_prepared = $wpdb->prepare( "
  458. SELECT x.term_taxonomy_id FROM {$wpdb->term_taxonomy} x JOIN {$wpdb->terms} t ON t.term_id = x.term_id
  459. WHERE t.slug=%s AND x.taxonomy='post_tag'", $_GET[ 'tag' ] );
  460. $tag_tax_id = $wpdb->get_var( $tag_tax_id_prepared );
  461. $language_code_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations
  462. WHERE element_type='tax_post_tag' AND element_id=%d", $tag_tax_id );
  463. $this->this_lang = $wpdb->get_var( $language_code_prepared );
  464. }
  465. //
  466. if ( !isset( $_GET[ 'lang' ] ) && ( $this->this_lang && $this->this_lang != $default_language ) ) {
  467. if ( !isset( $GLOBALS[ 'wp_rewrite' ] ) ) {
  468. require_once ABSPATH . WPINC . '/rewrite.php';
  469. $GLOBALS[ 'wp_rewrite' ] = new WP_Rewrite();
  470. }
  471. define( 'ICL_DOING_REDIRECT', true );
  472. if ( isset( $_GET[ 'page_id' ] ) ) {
  473. wp_redirect( get_page_link( $_GET[ 'page_id' ] ), '301' );
  474. exit;
  475. } elseif ( isset( $_GET[ 'p' ] ) ) {
  476. wp_redirect( get_permalink( $_GET[ 'p' ] ), '301' );
  477. exit;
  478. } elseif ( isset( $_GET[ 'cat_ID' ] ) ) {
  479. wp_redirect( get_term_link( intval( $_GET[ 'cat_ID' ] ), 'category' ) );
  480. exit;
  481. } elseif ( isset( $_GET[ 'tag' ] ) ) {
  482. wp_redirect( get_term_link( $_GET[ 'tag' ], 'post_tag' ) );
  483. exit;
  484. } else {
  485. if ( isset( $this->settings[ 'taxonomies_sync_option' ] ) ) {
  486. $taxs = array_keys( (array)$this->settings[ 'taxonomies_sync_option' ] );
  487. foreach ( $taxs as $t ) {
  488. if ( isset( $_GET[ $t ] ) ) {
  489. $term_obj = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} x ON t.term_id = x.term_id
  490. WHERE t.slug=%s AND x.taxonomy=%s", $_GET[ $t ], $t ) );
  491. $term_link = get_term_link( $term_obj, $t );
  492. $term_link = str_replace( '&amp;', '&', $term_link ); // fix
  493. if ( $term_link && !is_wp_error( $term_link ) ) {
  494. wp_redirect( $term_link );
  495. exit;
  496. }
  497. }
  498. }
  499. }
  500. }
  501. }
  502. if ( empty( $this->this_lang ) ) {
  503. $this->this_lang = $default_language;
  504. }
  505. }
  506. // allow forcing the current language when it can't be decoded from the URL
  507. $this->this_lang = apply_filters( 'icl_set_current_language', $this->this_lang );
  508. }
  509. //reorder active language to put 'this_lang' in front
  510. foreach ( $this->active_languages as $k => $al ) {
  511. if ( $al[ 'code' ] == $this->this_lang ) {
  512. unset( $this->active_languages[ $k ] );
  513. $this->active_languages = array_merge( array( $k => $al ), $this->active_languages );
  514. }
  515. }
  516. WPML_Troubleshooting_Terms_Menu::display_terms_with_suffix_admin_notice();
  517. // filter some queries
  518. add_filter( 'query', array( $this, 'filter_queries' ) );
  519. add_filter( 'option_rewrite_rules', array( $this, 'rewrite_rules_filter' ) );
  520. $this->set_language_cookie();
  521. if ( is_admin() && ( !isset( $_GET[ 'page' ] ) || !defined( 'WPML_ST_FOLDER' ) || $_GET[ 'page' ] != WPML_ST_FOLDER . '/menu/string-translation.php' ) && ( !isset( $_GET[ 'page' ] ) || !defined( 'WPML_TM_FOLDER' ) || $_GET[ 'page' ] != WPML_TM_FOLDER . '/menu/translations-queue.php' )
  522. ) {
  523. if ( version_compare( $GLOBALS[ 'wp_version' ], '3.3', '<' ) ) {
  524. // Legacy code for admin language switcher
  525. if ( !$this->is_rtl() && version_compare( $GLOBALS[ 'wp_version' ], '3.3', '>' ) ) {
  526. add_action( 'admin_notices', 'wpml_set_admin_language_switcher_place', 100 );
  527. add_action( 'network_admin_notices', 'wpml_set_admin_language_switcher_place', 100 );
  528. add_action( 'user_admin_notices', 'wpml_set_admin_language_switcher_place', 100 );
  529. function wpml_set_admin_language_switcher_place()
  530. {
  531. echo '<br clear="all" />';
  532. }
  533. }
  534. add_action( 'in_admin_header', array( $this, 'admin_language_switcher_legacy' ) );
  535. } else {
  536. // Admin language switcher goes to the WP admin bar
  537. add_action( 'wp_before_admin_bar_render', array( $this, 'admin_language_switcher' ) );
  538. }
  539. }
  540. if ( !is_admin() && defined( 'DISQUS_VERSION' ) ) {
  541. include ICL_PLUGIN_PATH . '/modules/disqus.php';
  542. }
  543. }
  544. /*
  545. * If user perform bulk taxonomy deletion when displaying non-default
  546. * language taxonomies, after deletion should stay with same language
  547. */
  548. if ( is_admin() &&
  549. isset($_POST['_wp_http_referer'])
  550. && false !== strpos($_POST['_wp_http_referer'], 'edit-tags.php')
  551. && !empty($_POST['delete_tags'])
  552. && is_array($_POST['delete_tags'])
  553. && !empty($_GET['lang'])
  554. && (
  555. $_POST['action'] == 'delete' || $_POST['action2'] == 'delete'
  556. ) ) {
  557. add_filter('wp_redirect', array($this, 'preserve_lang_param_after_bulk_category_delete'));
  558. }
  559. if ( $this->is_rtl() ) {
  560. $GLOBALS[ 'text_direction' ] = 'rtl';
  561. }
  562. if (!wpml_is_ajax() && is_admin() && empty( $this->settings[ 'dont_show_help_admin_notice' ] ) ) {
  563. if ( !$this->get_setting('setup_wizard_step') ) {
  564. if(SitePress::check_settings_integrity()) {
  565. add_action( 'admin_notices', array( $this, 'help_admin_notice' ) );
  566. }
  567. }
  568. }
  569. $short_v = implode( '.', array_slice( explode( '.', ICL_SITEPRESS_VERSION ), 0, 3 ) );
  570. if ( is_admin() && ( !isset( $this->settings[ 'hide_upgrade_notice' ] ) || $this->settings[ 'hide_upgrade_notice' ] != $short_v ) ) {
  571. add_action( 'admin_notices', array( $this, 'upgrade_notice' ) );
  572. }
  573. require ICL_PLUGIN_PATH . '/inc/template-constants.php';
  574. if ( defined( 'WPML_LOAD_API_SUPPORT' ) ) {
  575. require ICL_PLUGIN_PATH . '/inc/wpml-api.php';
  576. }
  577. add_action( 'wp_footer', array( $this, 'display_wpml_footer' ), 20 );
  578. if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
  579. add_action( 'xmlrpc_call', array( $this, 'xmlrpc_call_actions' ) );
  580. add_filter( 'xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
  581. }
  582. if ( defined( 'WPML_TM_VERSION' ) && is_admin() ) {
  583. require ICL_PLUGIN_PATH . '/inc/quote.php';
  584. }
  585. add_action( 'init', array( $this, 'set_up_language_selector' ) );
  586. global $pagenow;
  587. if ( $pagenow == 'admin-ajax.php' ) {
  588. if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'wpml_tt_show_terms') {
  589. $default_language = $this->get_default_language();
  590. //@todo: remove the following live after WPML 3.5 release
  591. //$this->switch_lang($default_language, true);
  592. }
  593. }
  594. // set language to default and remove language switcher when in Taxonomy Translation page
  595. // If the page uses AJAX and the language must be forced to default, please use the
  596. // if ( $pagenow == 'admin-ajax.php' )above
  597. if ( is_admin() && isset( $_GET[ 'page' ] ) && ( $_GET[ 'page' ] == ICL_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' || $_GET[ 'page' ] == ICL_PLUGIN_FOLDER . '/menu/menus-sync.php' ) ) {
  598. $default_language = $this->get_admin_language();
  599. $this->switch_lang($default_language, true);
  600. add_action( 'init', array( $this, 'remove_admin_language_switcher'));
  601. }
  602. /* Posts and new inline created terms, can only be saved in an active language.
  603. * Also the content of the post-new.php should always be filtered for one specific
  604. * active language, so to display the correct taxonomy terms for selection.
  605. */
  606. if ( $pagenow == 'post-new.php' ) {
  607. if ( ! $this->is_active_language( $this->get_current_language() ) ) {
  608. $default_language = $this->get_admin_language();
  609. $this->switch_lang( $default_language, true );
  610. }
  611. }
  612. //Code to run when reactivating the plugin
  613. $recently_activated = $this->get_setting('just_reactivated');
  614. if($recently_activated) {
  615. add_action( 'init', array( $this, 'rebuild_language_information' ), 1000 );
  616. }
  617. do_action('wpml_after_init');
  618. }
  619. /**
  620. * @param bool|String $requested_url String If this is specified the value of $url will be checked for whether it's the root page.
  621. * Checks whether the currently requested page is the root page.
  622. *
  623. * @return bool
  624. */
  625. function is_root_page( $requested_url = false ) {
  626. /*
  627. * A request leads to the root page under the following conditions.
  628. *
  629. * 1. The get parameter on it specifically requests the root page via either:
  630. * ?preview_id = {root_page_id}
  631. * ?page_id = {root_page_id}
  632. * ?p = {root_page_id}
  633. *
  634. * 2. The root page slug is the first slug after the domain.
  635. *
  636. * 3. There is no slug after the domain and the get parameters are not set as to redirect
  637. * to another page meaning:
  638. * no ?p, ?page_id or similar query parameter redirects to another post/page
  639. * no get parameter such as ?cat redirects to an archive page
  640. *
  641. */
  642. $is_root = true;
  643. // before checking anything see if the site even uses a root page
  644. $urls = $this->get_setting( 'urls' );
  645. if ( ! $urls
  646. || ! isset( $urls[ 'directory_for_default_language' ] )
  647. || ! $urls[ 'directory_for_default_language' ]
  648. || ! isset( $urls[ 'root_page' ] )
  649. || $urls[ 'root_page' ] == 0
  650. ) {
  651. $is_root = false;
  652. } elseif ( isset( $_SERVER[ 'REQUEST_URI' ] ) || $requested_url !== false ) {
  653. $root_id = $urls[ 'root_page' ];
  654. $root_slug = false;
  655. if ( $root_id ) {
  656. $root_page_object = get_post( $root_id );
  657. if ( $root_page_object && isset( $root_page_object->post_name ) ) {
  658. $root_slug = $root_page_object->post_name;
  659. }
  660. }
  661. if ( $root_slug === false ) {
  662. $is_root = false;
  663. } else {
  664. if ( $requested_url ) {
  665. $request_uri = parse_url( $requested_url, PHP_URL_PATH );
  666. $query_string = parse_url( $requested_url, PHP_URL_QUERY );
  667. if( $query_string ) {
  668. $request_uri .= '?' . $query_string;
  669. }
  670. } else {
  671. $request_uri = $_SERVER[ 'REQUEST_URI' ];
  672. }
  673. //If the get parameter ? is not preceeded by a /, add a '/'
  674. if ( strpos( $request_uri, '?' ) !== false && strpos( $request_uri, '/?' ) === false ) {
  675. $request_uri = str_replace( '?', '/?', $request_uri );
  676. }
  677. $request_uri = wpml_strip_subdir_from_url( $request_uri );
  678. //First get the slug of the requested url, should there be one.
  679. $slugs_and_get_params = explode( '/', $request_uri );
  680. foreach ( $slugs_and_get_params as $key => $slug ) {
  681. if ( ! trim( $slug ) ) {
  682. unset( $slugs_and_get_params[ $key ] );
  683. }
  684. }
  685. // if we have any slugs or get parameters it could be we are not on the root page
  686. if ( ! empty( $slugs_and_get_params ) ) {
  687. $get_query_string = '';
  688. // First of all see if we have get parameters
  689. if ( isset( $_GET ) && ! empty( $_GET ) ) {
  690. $get_query_string = array_pop( $slugs_and_get_params );
  691. /* In case we have get parameters we can instantly be sure to be on the root page
  692. * This can be done by either id parameters or by slug/name parameters.
  693. * ID parametes as of WP 4.1 are : p, page_id
  694. * Name parameters as of WP 4.1 are: name, pagename
  695. */
  696. if ( ( isset( $_GET[ 'p' ] ) && $_GET[ 'p' ] != $root_id )
  697. || ( isset( $_GET[ 'page_id' ] ) && $_GET[ 'page_id' ] != $root_id )
  698. || ( isset( $_GET[ 'name' ] ) && $_GET[ 'name' ] != $root_slug )
  699. || ( isset( $_GET[ 'pagename' ] ) && $_GET[ 'pagename' ] != $root_slug )
  700. ) {
  701. $is_root = false;
  702. }
  703. }
  704. /*
  705. * Next up there are other get parameters that allow us to recognize not being on the root page for certain.
  706. * These only come into play when neither of the above page parameters is set and therefore no specific page is queried for.
  707. */
  708. if ( ! ( isset( $_GET[ 'pagename' ] ) || isset( $_GET[ 'name' ] ) || isset( $_GET[ 'page_id' ] ) || isset( $_GET[ 'p' ] ) ) ) {
  709. /* The under these conditions excluded parameters, that ensure the root page to not be queried for, are determined in this way:
  710. * First we fetch all rewrite rules. This has to be done from the options cache since the actual rewrite object is not initialized yet.
  711. * Initializing it would impose a siginificant performance hit too.
  712. */
  713. $query = new WP_Query( str_replace( '?', '', $get_query_string ) );
  714. if ( ( $query->is_archive() ) ) {
  715. $is_root = false;
  716. }
  717. }
  718. // In case we have slugs, we need to check the last slug for whether it is the slug of the root page
  719. if ( $is_root && ! empty( $slugs_and_get_params ) ) {
  720. $slugs = $slugs_and_get_params;
  721. $last_slug = array_pop( $slugs );
  722. $second_slug = array_pop( $slugs );
  723. if ( ( $root_slug != $last_slug && ! is_numeric( $last_slug )
  724. || ( is_numeric( $last_slug ) && $second_slug != null && $root_slug != $second_slug && 'page' != $second_slug ) )
  725. && ( ! ( isset( $_GET[ 'p' ] ) && $_GET[ 'p' ] == $root_id )
  726. || ! ( isset( $_GET[ 'page_id' ] ) && $_GET[ 'page_id' ] == $root_id )
  727. || ! ( isset( $_GET[ 'name' ] ) && $_GET[ 'name' ] == $root_slug )
  728. || ! ( isset( $_GET[ 'pagename' ] ) && $_GET[ 'pagename' ] == $root_slug ) )
  729. ) {
  730. /* If the last slug is not the root slug or numeric,
  731. * then the current page is not the root page. This condition only holds though
  732. * in case no page/post parameters are appended to the request, that point towards the root page.
  733. */
  734. $is_root = false;
  735. }
  736. }
  737. }
  738. }
  739. }
  740. return $is_root;
  741. }
  742. /**
  743. * @param $url
  744. * Filters links to the root page, so that they are displayed properly in the front-end.
  745. *
  746. * @return mixed
  747. */
  748. function filter_root_permalink( $url ) {
  749. $urls = $this->get_setting( 'urls' );
  750. $root_id = $urls[ 'root_page' ];
  751. $root_page_object = get_post( $root_id );
  752. $url = str_replace( ' ', '', $url );
  753. $url = str_replace( '%20/', '/', $url );
  754. if ( $this->is_root_page( $url ) ) {
  755. $root_slug = $root_page_object->post_name;
  756. // Remove all whitespaces from urls
  757. $method = '';
  758. $new_url = str_replace( 'http://', '', $url );
  759. if ( $new_url != $url ) {
  760. $method = 'http://';
  761. } else {
  762. $new_url = str_replace( 'https://', '', $url );
  763. if ( $new_url != $url ) {
  764. $method = 'https://';
  765. }
  766. }
  767. $query = '';
  768. if ( strpos( $new_url, '?' ) !== false ) {
  769. $split_by_get_url = explode( '?', $new_url );
  770. $url_without_query = array_shift( $split_by_get_url );
  771. $query = implode( '?', $split_by_get_url );
  772. } else {
  773. $url_without_query = $new_url;
  774. }
  775. $slugs = explode( '/', $url_without_query );
  776. foreach ( $slugs as $key => $slug ) {
  777. if ( $slug == '' || strpos( $slug, parse_url( $url, PHP_URL_HOST ) ) !== false ) {
  778. unset( $slugs[ $key ] );
  779. }
  780. }
  781. $last_slug = array_pop( $slugs );
  782. $second_slug = array_pop( $slugs );
  783. if ( $second_slug == $root_slug && ( is_numeric( $last_slug ) || $last_slug == "" ) ) {
  784. $url_without_query = str_replace( '/' . $second_slug . '/', '/', $url_without_query );
  785. $potential_lang_slug = array_pop( $slugs );
  786. } elseif ( $last_slug == $root_slug ) {
  787. $url_without_query = str_replace( '/' . $last_slug, '/', $url_without_query );
  788. $potential_lang_slug = $second_slug;
  789. } else {
  790. $potential_lang_slug = array_pop( $slugs );
  791. }
  792. $all_langs = $this->get_active_languages();
  793. foreach ( $all_langs as $lang ) {
  794. if ( $lang[ 'code' ] == $potential_lang_slug ) {
  795. $url_without_query = str_replace( '/' . $potential_lang_slug, '/', $url_without_query );
  796. break;
  797. }
  798. }
  799. $new_url = trailingslashit($url_without_query);
  800. if ( $query != '' ) {
  801. $new_url = $new_url . '?' . $query;
  802. }
  803. /* Only if we actually have a root url, do we filter the url here.
  804. * This is to ensure that cases like url/wp-admin/members/root-slug are properly
  805. * differentiated from actualy root page calls, in case of root-slug's with
  806. * generic names potentially causing collisions.
  807. */
  808. if ( empty( $slugs ) ) {
  809. $url = $method . $new_url;
  810. }
  811. }
  812. return $url;
  813. }
  814. function load_dependencies() {
  815. do_action('wpml_load_dependencies');
  816. }
  817. /**
  818. * Sets up all term/taxonomy actions for use outside Translations Management or the Post Edit screen
  819. */
  820. function set_term_filters_and_hooks(){
  821. add_filter( 'terms_clauses', array( $this, 'terms_clauses' ), 10, 4 );
  822. add_filter( 'list_terms_exclusions', array( $this, 'exclude_other_terms' ), 1, 2 );
  823. add_filter( 'term_link', array( $this, 'tax_permalink_filter' ), 1, 2 );
  824. add_action( 'create_term', array( $this, 'create_term' ), 1, 2 );
  825. add_action( 'edit_term', array( $this, 'create_term' ), 1, 2 );
  826. add_filter( 'get_terms_args', array( $this, 'get_terms_args_filter' ) );
  827. add_filter( 'get_edit_term_link', array( $this, 'get_edit_term_link' ), 1, 4 );
  828. add_action('wp_ajax_icl_repair_broken_type_and_language_assignments', 'icl_repair_broken_type_and_language_assignments');
  829. //Taxonomies
  830. if ( version_compare( preg_replace( '#-RC[0-9]+(-[0-9]+)?$#', '', $GLOBALS[ 'wp_version' ] ), '3.1', '<' ) ) {
  831. add_filter( 'category_link', array( $this, 'category_permalink_filter' ), 1, 2 );
  832. add_filter( 'tag_link', array( $this, 'tax_permalink_filter' ), 1, 2 );
  833. }
  834. add_filter( 'taxonomy_template', array( $this, 'slug_template' ) );
  835. add_filter( 'category_template', array( $this, 'slug_template' ) );
  836. //post/page delete taxonomy
  837. add_action( 'deleted_term_relationships', array( $this, 'deleted_term_relationships' ), 10, 2 );
  838. // adjust queried categories and tags ids according to the language
  839. if ( $this->settings[ 'auto_adjust_ids' ] ) {
  840. add_action( 'parse_query', array( $this, 'parse_query' ) );
  841. add_action( 'wp_list_pages_excludes', array( $this, 'adjust_wp_list_pages_excludes' ) );
  842. if ( !is_admin() ) {
  843. add_filter( 'get_term', array( $this, 'get_term_adjust_id' ), 1, 1 );
  844. add_filter( 'category_link', array( $this, 'category_link_adjust_id' ), 1, 2 );
  845. add_filter( 'get_terms', array( $this, 'get_terms_adjust_ids' ), 1, 3 );
  846. add_filter( 'get_pages', array( $this, 'get_pages_adjust_ids' ), 1, 2 );
  847. }
  848. }
  849. }
  850. function icl_redirect_canonical_wrapper()
  851. {
  852. global $_icl_server_request_uri;
  853. $requested_url = ( !empty( $_SERVER[ 'HTTPS' ] ) && mb_strtolower( $_SERVER[ 'HTTPS' ] ) == 'on' ) ? 'https://' : 'http://';
  854. $requested_url .= $this->get_server_host_name();
  855. $requested_url .= $_icl_server_request_uri;
  856. redirect_canonical( $requested_url );
  857. }
  858. /**
  859. * If user perform bulk taxonomy deletion when displaying non-default
  860. * language taxonomies, after deletion should stay with same language
  861. *
  862. * @param string $location Url where browser will redirect
  863. * @return string Url where browser will redirect
  864. */
  865. function preserve_lang_param_after_bulk_category_delete($location) {
  866. if (empty($_GET['lang'])) {
  867. return $location;
  868. }
  869. $location = add_query_arg( 'lang', $_GET['lang'], $location );
  870. return $location;
  871. }
  872. function remove_admin_language_switcher() {
  873. remove_action( 'wp_before_admin_bar_render', array( $this, 'admin_language_switcher' ) );
  874. }
  875. function rebuild_language_information() {
  876. $this->set_setting('just_reactivated', 0);
  877. $this->save_settings();
  878. global $iclTranslationManagement;
  879. if ( isset( $iclTranslationManagement ) ) {
  880. $iclTranslationManagement->add_missing_language_information();
  881. }
  882. }
  883. function on_wp_init()
  884. {
  885. if ( is_admin() && current_user_can( 'manage_options' ) ) {
  886. if ( $this->icl_account_configured() ) {
  887. add_action( 'admin_notices', array( $this, 'icl_reminders' ) );
  888. }
  889. }
  890. include ICL_PLUGIN_PATH . '/inc/translation-management/taxonomy-translation.php';
  891. }
  892. function setup()
  893. {
  894. $setup_complete = $this->get_setting('setup_complete');
  895. if(!$setup_complete) {
  896. $this->set_setting('setup_complete', false);
  897. }
  898. return $setup_complete;
  899. }
  900. function get_current_user()
  901. {
  902. global $current_user;
  903. if ( did_action( 'set_current_user' ) ) {
  904. return $current_user;
  905. } else {
  906. return $this->current_user; // created early / no authentication
  907. }
  908. }
  909. function ajax_setup()
  910. {
  911. require ICL_PLUGIN_PATH . '/ajax.php';
  912. }
  913. function check_if_admin_action_from_referer() {
  914. $result = false;
  915. if ( isset( $_SERVER[ 'HTTP_REFERER' ] ) ) {
  916. $http_referer = parse_url( $_SERVER[ 'HTTP_REFERER' ] );
  917. $referer_path = $http_referer[ 'path' ];
  918. $referer_parts = explode( '/', $referer_path );
  919. if ( in_array( 'wp-admin', $referer_parts ) ) {
  920. $result = true;
  921. }
  922. }
  923. return $result;
  924. }
  925. function configure_custom_column()
  926. {
  927. global $pagenow, $wp_post_types;
  928. $pagenow_ = '';
  929. $is_ajax = false;
  930. if ( $pagenow == 'admin-ajax.php' ) {
  931. if ( isset( $_POST[ 'action' ] ) && $_POST[ 'action' ] == 'inline-save' || isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'fetch-list'
  932. ) {
  933. $is_ajax = true;
  934. }
  935. }
  936. if ( ( $pagenow == 'edit.php' || $pagenow_ == 'edit-pages.php' || $is_ajax ) ) {
  937. $post_type = isset( $_REQUEST[ 'post_type' ] ) ? $_REQUEST[ 'post_type' ] : 'post';
  938. switch ( $post_type ) {
  939. case 'post':
  940. case 'page':
  941. add_filter( 'manage_' . $post_type . 's_columns', array( $this, 'add_posts_management_column' ) );
  942. if ( isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'page' ) {
  943. add_action( 'manage_' . $post_type . 's_custom_column', array( $this, 'add_content_for_posts_management_column' ) );
  944. }
  945. add_action( 'manage_posts_custom_column', array( $this, 'add_content_for_posts_management_column' ) );
  946. break;
  947. default:
  948. if ( in_array( $post_type, array_keys( $this->get_translatable_documents() ) ) ) {
  949. add_filter( 'manage_' . $post_type . '_posts_columns', array( $this, 'add_posts_management_column' ) );
  950. if ( $wp_post_types[ $post_type ]->hierarchical ) {
  951. add_action( 'manage_pages_custom_column', array( $this, 'add_content_for_posts_management_column' ) );
  952. add_action( 'manage_posts_custom_column', array( $this, 'add_content_for_posts_management_column' ) ); // add this too - for more types plugin
  953. } else {
  954. add_action( 'manage_posts_custom_column', array( $this, 'add_content_for_posts_management_column' ) );
  955. }
  956. }
  957. }
  958. add_action( 'admin_print_scripts', array( $this, '__set_posts_management_column_width' ) );
  959. }
  960. }
  961. function _taxonomy_languages_menu()
  962. {
  963. // tags language selection
  964. global $pagenow;
  965. if ( $pagenow == 'edit-tags.php' ) {
  966. // handle case of the tax edit page (after a taxonomy has been added)
  967. // needs to redirect back to
  968. if ( isset( $_GET[ 'trid' ] ) && isset( $_GET[ 'source_lang' ] ) ) {
  969. $translations = $this->get_element_translations( $_GET[ 'trid' ], 'tax_' . $_GET[ 'taxonomy' ] );
  970. if ( isset( $translations[ $_GET[ 'lang' ] ] ) ) {
  971. wp_redirect( get_edit_term_link( $translations[ $_GET[ 'lang' ] ]->term_id, $_GET[ 'taxonomy' ] ) );
  972. exit;
  973. } else {
  974. add_action( 'admin_notices', array( $this, '_tax_adding' ) );
  975. }
  976. }
  977. $taxonomy = isset( $_GET[ 'taxonomy' ] ) ? esc_sql( $_GET[ 'taxonomy' ] ) : 'post_tag';
  978. if ( $this->is_translated_taxonomy( $taxonomy ) ) {
  979. add_action( 'admin_print_scripts-edit-tags.php', array( $this, 'js_scripts_tags' ) );
  980. if ( $taxonomy == 'category' ) {
  981. add_action( 'edit_category_form', array( $this, 'edit_term_form' ) );
  982. } else {
  983. add_action( 'add_tag_form', array( $this, 'edit_term_form' ) );
  984. add_action( 'edit_tag_form', array( $this, 'edit_term_form' ) );
  985. }
  986. add_action( 'admin_footer', array( $this, 'terms_language_filter' ) );
  987. add_filter( 'wp_dropdown_cats', array( $this, 'wp_dropdown_cats_select_parent' ) );
  988. }
  989. }
  990. }
  991. function _tax_adding()
  992. {
  993. $translations = $this->get_element_translations( $_GET[ 'trid' ], 'tax_' . $_GET[ 'taxonomy' ] );
  994. if ( !empty( $translations ) && isset( $translations[ $_GET[ 'source_lang' ] ]->name ) ) {
  995. $tax_name = apply_filters( 'the_category', $translations[ $_GET[ 'source_lang' ] ]->name );
  996. echo '<div id="icl_tax_adding_notice" class="updated fade"><p>' . sprintf( __( 'Adding translation for: %s.', 'sitepress' ), $tax_name ) . '</p></div>';
  997. }
  998. }
  999. /**
  1000. * @param WP_Query $query
  1001. */
  1002. function loop_start($query) {
  1003. if ( isset( $query->post_count ) && $query->post_count ) {
  1004. $this->cache_translations( $query->posts );
  1005. }
  1006. }
  1007. /**
  1008. * Cache translated posts
  1009. *
  1010. * @param $posts
  1011. */
  1012. function cache_translations($posts) {
  1013. global $wpdb, $wp_query, $sitepress;
  1014. static $last_query=false;
  1015. if ( defined( 'WPML_DISABLE_CACHE_TRANSLATIONS' ) && is_admin() ){
  1016. return;
  1017. }
  1018. if ( isset( $sitepress ) && isset( $wp_query ) && $wp_query->is_main_query() ) {
  1019. if($last_query == $wp_query->query_vars_hash) return;
  1020. $sticky_posts_ids = get_option( 'sticky_posts' );
  1021. if ( $sticky_posts_ids ) {
  1022. if ( count( $sticky_posts_ids ) == 1 ) {
  1023. $sticky_posts_prepared = $wpdb->prepare( "SELECT * FROM {$wpdb->posts} WHERE ID = %d", array( $sticky_posts_ids[0] ) );
  1024. } else {
  1025. $sticky_posts_prepared = "SELECT * FROM {$wpdb->posts} WHERE ID IN (" . implode( ',', array_filter( $sticky_posts_ids ) ) . ")";
  1026. }
  1027. $sticky_posts = $wpdb->get_results( $sticky_posts_prepared );
  1028. $posts_objects = array_map( 'get_post', $sticky_posts );
  1029. if ( !$posts ) {
  1030. $posts = $posts_objects;
  1031. } else {
  1032. $posts = array_merge( $posts, $posts_objects );
  1033. //Remove duplicates
  1034. $posts = array_map( "unserialize", array_unique( array_map( "serialize", $posts ) ) );
  1035. }
  1036. }
  1037. if ( $posts ) {
  1038. $terms = array();
  1039. //Query specific cache
  1040. $cache_key = $wp_query->query_vars_hash;
  1041. $cache_group = 'wp_query:posts_translations';
  1042. $cached_posts_translations = wp_cache_get( $cache_key, $cache_group );
  1043. if ( !$cached_posts_translations ) {
  1044. $post_types = array();
  1045. foreach ( $posts as $post ) {
  1046. $post_types[ $post->post_type ][] = $post->ID;
  1047. }
  1048. $trids = array();
  1049. if ( $post_types ) {
  1050. $trid_cache_group = 'element_trid';
  1051. foreach ( $post_types as $post_type => $posts_ids ) {
  1052. $element_type = 'post_' . $post_type;
  1053. $s_post_type_ids = join( ',', array_filter($posts_ids) );
  1054. $trids_prepared = $wpdb->prepare( "SELECT trid, element_id, language_code, source_language_code FROM {$wpdb->prefix}icl_translations WHERE element_id IN (" . $s_post_type_ids . ") AND element_type=%s GROUP BY trid", array( $element_type ) );
  1055. $post_type_trids_data = $wpdb->get_results( $trids_prepared );
  1056. foreach($post_type_trids_data as $post_type_trid_data) {
  1057. $element_id = $post_type_trid_data->element_id;
  1058. $trid_cache_key = $element_id . ':post_' . $post_type;
  1059. $trid = wp_cache_get($trid_cache_key, $trid_cache_group);
  1060. if(!$trid) {
  1061. $trid = $post_type_trid_data->trid;
  1062. $trids[] = $trid;
  1063. wp_cache_add($trid_cache_key, $trid, $trid_cache_group);
  1064. }
  1065. if($trid) {
  1066. $element_language_details_cache_group = 'element_language_details';
  1067. $element_language_details = wp_cache_get($trid_cache_key, $element_language_details_cache_group);
  1068. if(!$element_language_details) {
  1069. $details = new stdClass();
  1070. $details->trid = $trid;
  1071. $details->language_code = $post_type_trid_data->language_code;
  1072. $details->source_language_code = $post_type_trid_data->source_language_code;
  1073. wp_cache_add($trid_cache_key, $details, $element_language_details_cache_group);
  1074. }
  1075. }
  1076. //Deal with taxonomies
  1077. //$_taxonomies = get_post_taxonomies($element_id);
  1078. $_taxonomies= get_post_taxonomies($element_id);
  1079. foreach($_taxonomies as $_taxonomy) {
  1080. if($sitepress->is_translated_taxonomy($_taxonomy)) {
  1081. $_terms = wp_get_post_terms($element_id, $_taxonomy);
  1082. foreach($_terms as $_term) {
  1083. $terms[$_term->taxonomy][] = $_term->term_id;
  1084. }
  1085. }
  1086. }
  1087. }
  1088. }
  1089. }
  1090. if ( $trids ) {
  1091. if(count($trids)==1) {
  1092. $posts_translations_prepared = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}icl_translations WHERE trid = %d ", array($trids[0]) );
  1093. }else {
  1094. $posts_translations_prepared = "SELECT * FROM {$wpdb->prefix}icl_translations WHERE trid IN (" . join( ',', array_filter($trids) ) . ") ";
  1095. }
  1096. $posts_translations = $wpdb->get_results( $posts_translations_prepared );
  1097. $post_ids = array();
  1098. foreach($posts_translations as $posts_translation) {
  1099. $post_ids[] = $posts_translation->element_id;
  1100. }
  1101. $posts_data = wp_cache_get($cache_key, 'wp_query:posts');
  1102. if(!$posts_data && $post_ids) {
  1103. $posts_prepared = "SELECT * FROM {$wpdb->posts} WHERE ID IN (" . join( ',', array_filter($post_ids) ) . ") ";
  1104. $posts_data = $wpdb->get_results( $posts_prepared );
  1105. wp_cache_set($cache_key, $posts_data, 'wp_query:posts');
  1106. }
  1107. if ( $posts_data ) {
  1108. foreach($posts_data as $post) {
  1109. $_post = wp_cache_get( $post->ID, 'posts' );
  1110. if ( ! $_post ) {
  1111. $_post = $post;
  1112. $_post = sanitize_post( $_post, 'raw' );
  1113. wp_cache_add( $_post->ID, $_post, 'posts' );
  1114. }
  1115. }
  1116. }
  1117. }
  1118. if ( $terms ) {
  1119. $cache_group = 'element_language_details';
  1120. foreach ( $terms as $taxonomy => $term_ids ) {
  1121. $element_type = 'tax_' . $taxonomy;
  1122. $terms_translations_prepared = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type = %s AND element_id IN (" . join( ',', $term_ids ) . ")", array( $element_type ) );
  1123. $terms_translations = $wpdb->get_results( $terms_translations_prepared );
  1124. foreach ( $terms_translations as $terms_translation ) {
  1125. $cache_key = $terms_translation->element_id . ':' . $terms_translation->element_type;
  1126. $cached_details = wp_cache_get( $cache_key, $cache_group );
  1127. if ( !$cached_details ) {
  1128. wp_cache_set( $cache_key, $terms_translation, $cache_group );
  1129. }
  1130. $icl_object_id_cache_group = 'icl_object_id';
  1131. $icl_object_id_cache_key_args = array( $terms_translation->element_id, $taxonomy, false, $terms_translation->language_code );
  1132. $icl_object_id_cache_key = implode( ':', array_filter( $icl_object_id_cache_key_args ) );
  1133. $icl_object_id = wp_cache_get( $cache_key, $cache_group );
  1134. if ( !$icl_object_id ) {
  1135. wp_cache_set( $icl_object_id_cache_key, $terms_translation->element_id, $icl_object_id_cache_group );
  1136. }
  1137. $icl_object_id_cache_key_args = array( $terms_translation->element_id, $taxonomy, true, $terms_translation->language_code );
  1138. $icl_object_id_cache_key = implode( ':', array_filter( $icl_object_id_cache_key_args ) );
  1139. $icl_object_id = wp_cache_get( $cache_key, $cache_group );
  1140. if ( !$icl_object_id ) {
  1141. wp_cache_set( $icl_object_id_cache_key, $terms_translation->element_id, $icl_object_id_cache_group );
  1142. }
  1143. }
  1144. }
  1145. }
  1146. }
  1147. }
  1148. $last_query = $wp_query->query_vars_hash;
  1149. }
  1150. }
  1151. function the_posts( $posts ) {
  1152. if ( !is_admin() && isset( $this->settings[ 'show_untranslated_blog_posts' ] ) && $this->settings[ 'show_untranslated_blog_posts' ] && $this->get_current_language() != $this->get_default_language() ) {
  1153. // show untranslated posts
  1154. global $wpdb, $wp_query;
  1155. $default_language = $this->get_default_language();
  1156. $current_language = $this->get_current_language();
  1157. $debug_backtrace = $this->get_backtrace(4, true); //Limit to first 4 stack frames, since 3 is the highest index we use
  1158. /** @var $custom_wp_query WP_Query */
  1159. $custom_wp_query = isset( $debug_backtrace[ 3 ][ 'object' ] ) ? $debug_backtrace[ 3 ][ 'object' ] : false;
  1160. //exceptions
  1161. if ( ( $current_language == $default_language )
  1162. // original language
  1163. ||
  1164. ( $wp_query != $custom_wp_query )
  1165. // called by a custom query
  1166. ||
  1167. ( !$custom_wp_query->is_posts_page && !$custom_wp_query->is_home )
  1168. // not the blog posts page
  1169. ||
  1170. $wp_query->is_singular
  1171. //is singular
  1172. ||
  1173. !empty( $custom_wp_query->query_vars[ 'category__not_in' ] )
  1174. //|| !empty($custom_wp_query->query_vars['category__in'])
  1175. //|| !empty($custom_wp_query->query_vars['category__and'])
  1176. ||
  1177. !empty( $custom_wp_query->query_vars[ 'tag__not_in' ] ) ||
  1178. !empty( $custom_wp_query->query_vars[ 'post__in' ] ) ||
  1179. !empty( $custom_wp_query->query_vars[ 'post__not_in' ] ) ||
  1180. !empty( $custom_wp_query->query_vars[ 'post_parent' ] )
  1181. ) {
  1182. return $posts;
  1183. }
  1184. // get the posts in the default language instead
  1185. $this_lang = $this->this_lang;
  1186. $this->this_lang = $default_language;
  1187. remove_filter( 'the_posts', array( $this, 'the_posts' ) );
  1188. $custom_wp_query->query_vars[ 'suppress_filters' ] = 0;
  1189. if ( isset( $custom_wp_query->query_vars[ 'pagename' ] ) && !empty( $custom_wp_query->query_vars[ 'pagename' ] ) ) {
  1190. if ( isset( $custom_wp_query->queried_object_id ) && !empty( $custom_wp_query->queried_object_id ) ) {
  1191. $page_id = $custom_wp_query->queried_object_id;
  1192. } else {
  1193. // urlencode added for languages that have urlencoded post_name field value
  1194. $custom_wp_query->query_vars[ 'pagename' ] = urlencode( $custom_wp_query->query_vars[ 'pagename' ] );
  1195. $page_id = $wpdb->get_var( "SELECT ID FROM {$wpdb->posts} WHERE post_name='{$custom_wp_query->query_vars['pagename']}' AND post_type='page'" );
  1196. }
  1197. if ( $page_id ) {
  1198. $tr_page_id = icl_object_id( $page_id, 'page', false, $default_language );
  1199. if ( $tr_page_id ) {
  1200. $custom_wp_query->query_vars[ 'pagename' ] = $wpdb->get_var( "SELECT post_name FROM {$wpdb->posts} WHERE ID={$tr_page_id}" );
  1201. }
  1202. }
  1203. }
  1204. // look for posts without translations
  1205. if ( $posts ) {
  1206. $pids = false;
  1207. foreach ( $posts as $p ) {
  1208. $pids[ ] = $p->ID;
  1209. }
  1210. if ( $pids ) {
  1211. $trids = $wpdb->get_col( "
  1212. SELECT trid
  1213. FROM {$wpdb->prefix}icl_translations
  1214. WHERE element_type='post_post' AND element_id IN (" . join( ',', $pids ) . ") AND language_code = '" . $this_lang . "'" );
  1215. if ( !empty( $trids ) ) {
  1216. $posts_not_translated = $wpdb->get_col( "
  1217. SELECT element_id, COUNT(language_code) AS c
  1218. FROM {$wpdb->prefix}icl_translations
  1219. WHERE trid IN (" . join( ',', $trids ) . ") GROUP BY trid HAVING c = 1
  1220. " );
  1221. if ( !empty( $posts_not_translated ) ) {
  1222. $GLOBALS[ '__icl_the_posts_posts_not_translated' ] = $posts_not_translated;
  1223. add_filter( 'posts_where', array( $this, '_posts_untranslated_extra_posts_where' ), 99 );
  1224. }
  1225. }
  1226. }
  1227. }
  1228. //fix page for posts
  1229. unset( $custom_wp_query->query_vars[ 'pagename' ] );
  1230. unset( $custom_wp_query->query_vars[ 'page_id' ] );
  1231. unset( $custom_wp_query->query_vars[ 'p' ] );
  1232. $my_query = new WP_Query( $custom_wp_query->query_vars );
  1233. add_filter( 'the_posts', array( $this, 'the_posts' ) );
  1234. $this->this_lang = $this_lang;
  1235. // create a map of the translated posts
  1236. foreach ( $posts as $post ) {
  1237. $trans_posts[ $post->ID ] = $post;
  1238. }
  1239. // loop original posts
  1240. foreach ( $my_query->posts as $k => $post ) { // loop posts in the default language
  1241. $trid = $this->get_element_trid( $post->ID );
  1242. $translations = $this->get_element_translations( $trid ); // get translations
  1243. if ( isset( $translations[ $current_language ] ) ) { // if there is a translation in the current language
  1244. if ( isset( $trans_posts[ $translations[ $current_language ]->element_id ] ) ) { //check the map of translated posts
  1245. $my_query->posts[ $k ] = $trans_posts[ $translations[ $current_language ]->element_id ];
  1246. } else { // check if the translated post exists in the database still
  1247. $_post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d AND post_status='publish' LIMIT 1", $translations[ $current_language ]->element_id ) );
  1248. if ( !empty( $_post ) ) {
  1249. $_post = sanitize_post( $_post );
  1250. $my_query->posts[ $k ] = $_post;
  1251. } else {
  1252. $my_query->posts[ $k ]->original_language = true;
  1253. }
  1254. }
  1255. } else {
  1256. $my_query->posts[ $k ]->original_language = true;
  1257. }
  1258. }
  1259. if ( $custom_wp_query == $wp_query ) {
  1260. $wp_query->max_num_pages = $my_query->max_num_pages;
  1261. }
  1262. $posts = $my_query->posts;
  1263. unset( $GLOBALS[ '__icl_the_posts_posts_not_translated' ] );
  1264. remove_filter( 'posts_where', array( $this, '_posts_untranslated_extra_posts_where' ), 99 );
  1265. }
  1266. // cache translated posts
  1267. $this->cache_translations($posts);
  1268. return $posts;
  1269. }
  1270. function get_pages($pages, $r) {
  1271. $this->cache_translations($pages);
  1272. return $pages;
  1273. }
  1274. function _posts_untranslated_extra_posts_where( $where )
  1275. {
  1276. global $wpdb;
  1277. $where .= ' OR ' . $wpdb->posts . '.ID IN (' . join( ',', $GLOBALS[ '__icl_the_posts_posts_not_translated' ] ) . ')';
  1278. return $where;
  1279. }
  1280. function initialize_cache()
  1281. {
  1282. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  1283. $this->icl_translations_cache = new icl_cache();
  1284. $this->icl_locale_cache = new icl_cache( 'locale', true );
  1285. $this->icl_flag_cache = new icl_cache( 'flags', true );
  1286. $this->icl_language_name_cache = new icl_cache( 'language_name', true );
  1287. $this->icl_term_taxonomy_cache = new icl_cache();
  1288. }
  1289. function set_admin_language()
  1290. {
  1291. global $wpdb;
  1292. $default_language = $this->get_default_language();
  1293. $found = false;
  1294. $cache_key = "active_languages";
  1295. $cache_group = "set_admin_lang";
  1296. $active_languages = wp_cache_get($cache_key, $cache_group, false, $found);
  1297. if(!$found) {
  1298. //don't use method get_active_language()
  1299. $active_languages_col = $wpdb->get_col( "SELECT code FROM {$wpdb->prefix}icl_languages WHERE active=1" );
  1300. $active_languages = array_keys( $active_languages_col );
  1301. wp_cache_set($cache_key, $active_languages, $cache_group);
  1302. }
  1303. if ( !empty( $this->get_current_user()->ID ) ) {
  1304. $this->admin_language = $this->get_user_admin_language( $this->get_current_user()->ID );
  1305. }
  1306. if ( $this->admin_language != '' && !in_array( $this->admin_language, $active_languages ) ) {
  1307. delete_user_meta( $this->get_current_user()->ID, 'icl_admin_language' );
  1308. }
  1309. if ( empty( $this->settings[ 'admin_default_language' ] ) || !in_array( $this->settings[ 'admin_default_language' ], $active_languages ) ) {
  1310. $this->settings[ 'admin_default_language' ] = '_default_';
  1311. $this->save_settings();
  1312. }
  1313. if ( !$this->admin_language ) {
  1314. $this->admin_language = $this->settings[ 'admin_default_language' ];
  1315. }
  1316. if ( $this->admin_language == '_default_' && $default_language ) {
  1317. $this->admin_language = $default_language;
  1318. }
  1319. }
  1320. function get_admin_language()
  1321. {
  1322. $current_user = $this->get_current_user();
  1323. if ( isset( $current_user->ID ) && get_user_meta( $current_user->ID, 'icl_admin_language_for_edit', true ) && icl_is_post_edit() ) {
  1324. $admin_language = $this->get_current_language();
  1325. } else {
  1326. $admin_language = $this->admin_language;
  1327. }
  1328. return $admin_language;
  1329. }
  1330. function get_user_admin_language( $user_id )
  1331. {
  1332. static $lang = array();
  1333. if ( !isset( $lang[ $user_id ] ) ) {
  1334. $lang[ $user_id ] = get_user_meta( $user_id, 'icl_admin_language', true );
  1335. if ( empty( $lang[ $user_id ] ) ) {
  1336. $admin_default_language = $this->get_setting( 'admin_default_language' );
  1337. if ( $admin_default_language ) {
  1338. $lang[ $user_id ] = $admin_default_language;
  1339. }
  1340. if ( empty( $lang[ $user_id ] ) || '_default_' == $lang[ $user_id ] ) {
  1341. $lang[ $user_id ] = $this->get_admin_language();
  1342. }
  1343. }
  1344. }
  1345. return $lang[ $user_id ];
  1346. }
  1347. function administration_menu()
  1348. {
  1349. if(!SitePress::check_settings_integrity()) return;
  1350. ICL_AdminNotifier::removeMessage( 'setup-incomplete' );
  1351. $main_page = apply_filters( 'icl_menu_main_page', basename( ICL_PLUGIN_PATH ) . '/menu/languages.php' );
  1352. if ( SitePress_Setup::setup_complete() ) {
  1353. add_menu_page( __( 'WPML', 'sitepress' ), __( 'WPML', 'sitepress' ), 'wpml_manage_languages', $main_page, null, ICL_PLUGIN_URL . '/res/img/icon16.png' );
  1354. add_submenu_page( $main_page, __( 'Languages', 'sitepress' ), __( 'Languages', 'sitepress' ), 'wpml_manage_languages', basename( ICL_PLUGIN_PATH ) . '/menu/languages.php' );
  1355. //By Gen, moved Translation management after language, because problems with permissions
  1356. do_action( 'icl_wpml_top_menu_added' );
  1357. add_submenu_page( $main_page, __( 'Theme and plugins localization', 'sitepress' ), __( 'Theme and plugins localization', 'sitepress' ), 'wpml_manage_theme_and_plugin_localization', basename( ICL_PLUGIN_PATH ) . '/menu/theme-localization.php' );
  1358. if ( !defined( 'WPML_TM_VERSION' ) ) {
  1359. add_submenu_page( $main_page, __( 'Translation options', 'sitepress' ), __( 'Translation options', 'sitepress' ), 'wpml_manage_translation_options', basename( ICL_PLUGIN_PATH ) . '/menu/translation-options.php' );
  1360. }
  1361. } else {
  1362. $main_page = basename( ICL_PLUGIN_PATH ) . '/menu/languages.php';
  1363. add_menu_page( __( 'WPML', 'sitepress' ), __( 'WPML', 'sitepress' ), 'manage_options', $main_page, null, ICL_PLUGIN_URL . '/res/img/icon16.png' );
  1364. add_submenu_page( $main_page, __( 'Languages', 'sitepress' ), __( 'Languages', 'sitepress' ), 'wpml_manage_languages', $main_page );
  1365. if ((!isset($_REQUEST['page']) || $_REQUEST['page']!=ICL_PLUGIN_FOLDER . '/menu/troubleshooting.php') && !SitePress_Setup::languages_table_is_complete() ) {
  1366. $troubleshooting_url = admin_url( 'admin.php?page=' . ICL_PLUGIN_FOLDER . '/menu/troubleshooting.php' );
  1367. $troubleshooting_link = '<a href="' . $troubleshooting_url . '" title="' . esc_attr( __( 'Troubleshooting', 'sitepress' ) ) . '">' . __( 'Troubleshooting', 'sitepress' ) . '</a>';
  1368. $message = '';
  1369. $message .= __( 'WPML is missing some records in the languages tables and it cannot fully work until this issue is fixed.', 'sitepress' );
  1370. $message .= '<br />';
  1371. $message .= sprintf( __( 'Please go to the %s page and click on %s to fix this problem.', 'sitepress' ), $troubleshooting_link, __( 'Fix languages tables', 'sitepress' ) );
  1372. $message .= '<br />';
  1373. $message .= '<br />';
  1374. $message .= __( 'This warning will disappear once this issue is fixed.', 'sitepress' );
  1375. ICL_AdminNotifier::removeMessage( 'setup-incomplete' );
  1376. ICL_AdminNotifier::addMessage( 'setup-incomplete', $message, 'error', false, false, false, 'setup', true );
  1377. ICL_AdminNotifier::displayMessages( 'setup' );
  1378. }
  1379. }
  1380. add_submenu_page( $main_page, __( 'Support', 'sitepress' ), __( 'Support', 'sitepress' ), 'wpml_manage_support', ICL_PLUGIN_FOLDER . '/menu/support.php' );
  1381. $this->troubleshooting_menu(ICL_PLUGIN_FOLDER . '/menu/support.php');
  1382. $this->debug_information_menu(ICL_PLUGIN_FOLDER . '/menu/support.php');
  1383. }
  1384. private function troubleshooting_menu( $main_page ) {
  1385. $submenu_slug = basename( ICL_PLUGIN_PATH ) . '/menu/troubleshooting.php';
  1386. //if ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == $submenu_slug ) {
  1387. add_submenu_page( $main_page, __( 'Troubleshooting', 'sitepress' ), __( 'Troubleshooting', 'sitepress' ), 'wpml_manage_troubleshooting', $submenu_slug );
  1388. return $submenu_slug;
  1389. //}
  1390. }
  1391. private function debug_information_menu( $main_page ) {
  1392. $submenu_slug = basename( ICL_PLUGIN_PATH ) . '/menu/debug-information.php';
  1393. add_submenu_page( $main_page, __( 'Debug information', 'sitepress' ), __( 'Debug information', 'sitepress' ), 'wpml_manage_troubleshooting', $submenu_slug );
  1394. return $submenu_slug;
  1395. }
  1396. // lower priority
  1397. function administration_menu2()
  1398. {
  1399. if(!SitePress::check_settings_integrity()) return;
  1400. $main_page = apply_filters( 'icl_menu_main_page', ICL_PLUGIN_FOLDER . '/menu/languages.php' );
  1401. if ( $this->setup() ) {
  1402. add_submenu_page( $main_page, __( 'Taxonomy Translation', 'sitepress' ), __( 'Taxonomy Translation', 'sitepress' ), 'wpml_manage_taxonomy_translation', ICL_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' );
  1403. }
  1404. }
  1405. public function init_settings() {
  1406. if ($this->get_setting('setup_wizard_step') == 4 && $this->get_setting('setup_complete') && !ms_is_switched()) {
  1407. global $sitepress_settings;
  1408. $this->settings = get_option( 'icl_sitepress_settings' );
  1409. $sitepress_settings = $this->settings;
  1410. return $sitepress_settings;
  1411. }
  1412. return null;
  1413. }
  1414. function save_settings( $settings = null )
  1415. {
  1416. global $sitepress_settings;
  1417. if ( !is_null( $settings ) ) {
  1418. foreach ( $settings as $k => $v ) {
  1419. if ( is_array( $v ) ) {
  1420. foreach ( $v as $k2 => $v2 ) {
  1421. $this->settings[ $k ][ $k2 ] = $v2;
  1422. }
  1423. } else {
  1424. $this->settings[ $k ] = $v;
  1425. }
  1426. }
  1427. }
  1428. if ( !empty( $this->settings ) ) {
  1429. update_option( 'icl_sitepress_settings', $this->settings );
  1430. $sitepress_settings = $this->settings;
  1431. }
  1432. do_action( 'icl_save_settings', $settings );
  1433. }
  1434. private function check_settings() {
  1435. if ( !isset( $this->settings ) ) {
  1436. $this->settings = $this->init_settings();
  1437. }
  1438. }
  1439. /**
  1440. * @since 3.1
  1441. */
  1442. function get_settings()
  1443. {
  1444. $this->check_settings();
  1445. return $this->settings;
  1446. }
  1447. /**
  1448. * @param string $key
  1449. * @param mixed|bool $default
  1450. *
  1451. * @since 3.1
  1452. *
  1453. * @return bool|mixed
  1454. */
  1455. function get_setting($key, $default = false)
  1456. {
  1457. $this->check_settings();
  1458. return isset($this->settings[$key]) ? $this->settings[$key] : $default;
  1459. }
  1460. /**
  1461. * @param string $key
  1462. * @param mixed $value
  1463. * @param bool $save_now Immediately update the settings record in the DB
  1464. *
  1465. * @since 3.1
  1466. */
  1467. function set_setting($key, $value, $save_now = false)
  1468. {
  1469. $this->check_settings();
  1470. $this->settings[$key] = $value;
  1471. if($save_now) {
  1472. $this->save_settings();
  1473. }
  1474. }
  1475. function get_user_preferences()
  1476. {
  1477. if ( empty( $this->user_preferences ) ) {
  1478. $this->user_preferences = get_user_meta( $this->get_current_user()->ID, '_icl_preferences', true );
  1479. }
  1480. return $this->user_preferences;
  1481. }
  1482. function set_user_preferences($value) {
  1483. $this->user_preferences = $value;
  1484. }
  1485. function save_user_preferences()
  1486. {
  1487. update_user_meta( $this->get_current_user()->ID, '_icl_preferences', $this->user_preferences );
  1488. }
  1489. function get_option( $option_name )
  1490. {
  1491. return isset( $this->settings[ $option_name ] ) ? $this->settings[ $option_name ] : null;
  1492. }
  1493. function verify_settings()
  1494. {
  1495. $default_settings = array(
  1496. 'interview_translators' => 1,
  1497. 'existing_content_language_verified' => 0,
  1498. 'language_negotiation_type' => 3,
  1499. 'theme_localization_type' => 1,
  1500. 'icl_lso_header' => 0,
  1501. 'icl_lso_link_empty' => 0,
  1502. 'icl_lso_flags' => 0,
  1503. 'icl_lso_native_lang' => 1,
  1504. 'icl_lso_display_lang' => 1,
  1505. 'sync_page_ordering' => 1,
  1506. 'sync_page_parent' => 1,
  1507. 'sync_page_template' => 1,
  1508. 'sync_ping_status' => 1,
  1509. 'sync_comment_status' => 1,
  1510. 'sync_sticky_flag' => 1,
  1511. 'sync_private_flag' => 1,
  1512. 'sync_post_format' => 1,
  1513. 'sync_delete' => 0,
  1514. 'sync_delete_tax' => 0,
  1515. 'sync_post_taxonomies' => 1,
  1516. 'sync_post_date' => 0,
  1517. 'sync_taxonomy_parents' => 0,
  1518. 'translation_pickup_method' => 0,
  1519. 'notify_complete' => 1,
  1520. 'translated_document_status' => 1,
  1521. 'remote_management' => 0,
  1522. 'auto_adjust_ids' => 1,
  1523. 'alert_delay' => 0,
  1524. 'promote_wpml' => 0,
  1525. 'troubleshooting_options' => array( 'http_communication' => 1 ),
  1526. 'automatic_redirect' => 0,
  1527. 'remember_language' => 24,
  1528. 'icl_lang_sel_type' => 'dropdown',
  1529. 'icl_lang_sel_stype' => 'classic',
  1530. 'icl_lang_sel_orientation' => 'vertical',
  1531. 'icl_lang_sel_copy_parameters' => '',
  1532. 'icl_widget_title_show' => 1,
  1533. 'translated_document_page_url' => 'auto-generate',
  1534. 'sync_comments_on_duplicates ' => 0,
  1535. 'seo' => array( 'head_langs' => 1, 'canonicalization_duplicates' => 1 ),
  1536. 'posts_slug_translation' => array( 'on' => 0 ),
  1537. 'languages_order' => '',
  1538. 'urls' => array( 'directory_for_default_language' => 0, 'show_on_root' => '', 'root_html_file_path' => '', 'root_page' => 0, 'hide_language_switchers' => 1 )
  1539. );
  1540. //configured for three levels
  1541. $update_settings = false;
  1542. foreach ( $default_settings as $key => $value ) {
  1543. if ( is_array( $value ) ) {
  1544. foreach ( $value as $k2 => $v2 ) {
  1545. if ( is_array( $v2 ) ) {
  1546. foreach ( $v2 as $k3 => $v3 ) {
  1547. if ( !isset( $this->settings[ $key ][ $k2 ][ $k3 ] ) ) {
  1548. $this->settings[ $key ][ $k2 ][ $k3 ] = $v3;
  1549. $update_settings = true;
  1550. }
  1551. }
  1552. } else {
  1553. if ( !isset( $this->settings[ $key ][ $k2 ] ) ) {
  1554. $this->settings[ $key ][ $k2 ] = $v2;
  1555. $update_settings = true;
  1556. }
  1557. }
  1558. }
  1559. } else {
  1560. if ( !isset( $this->settings[ $key ] ) ) {
  1561. $this->settings[ $key ] = $value;
  1562. $update_settings = true;
  1563. }
  1564. }
  1565. }
  1566. if ( $update_settings ) {
  1567. $this->save_settings();
  1568. }
  1569. }
  1570. function _validate_language_per_directory( $language_code )
  1571. {
  1572. if ( !class_exists( 'WP_Http' ) ) {
  1573. include_once ABSPATH . WPINC . '/class-http.php';
  1574. }
  1575. $client = new WP_Http();
  1576. if ( false === @strpos( $_POST[ 'url' ], '?' ) ) {
  1577. $url_glue = '?';
  1578. } else {
  1579. $url_glue = '&';
  1580. }
  1581. $response = $client->request( get_home_url() . '/' . $language_code . '/' . $url_glue . '____icl_validate_domain=1', array( 'timeout' => 15, 'decompress' => false ) );
  1582. return ( !is_wp_error( $response ) && ( $response[ 'response' ][ 'code' ] == '200' ) && ( $response[ 'body' ] == '<!--' . get_home_url() . '-->' ) );
  1583. }
  1584. function save_language_pairs()
  1585. {
  1586. // clear existing languages
  1587. $lang_pairs = $this->settings[ 'language_pairs' ];
  1588. if ( is_array( $lang_pairs ) ) {
  1589. foreach ( $lang_pairs as $from => $to ) {
  1590. $lang_pairs[ $from ] = array();
  1591. }
  1592. }
  1593. // get the from languages
  1594. $from_languages = array();
  1595. foreach ( $_POST as $k => $v ) {
  1596. if ( 0 === strpos( $k, 'icl_lng_from_' ) ) {
  1597. $f = str_replace( 'icl_lng_from_', '', $k );
  1598. $from_languages[ ] = $f;
  1599. }
  1600. }
  1601. foreach ( $_POST as $k => $v ) {
  1602. if ( 0 !== strpos( $k, 'icl_lng_' ) ) {
  1603. continue;
  1604. }
  1605. if ( 0 === strpos( $k, 'icl_lng_to' ) ) {
  1606. $t = str_replace( 'icl_lng_to_', '', $k );
  1607. $exp = explode( '_', $t );
  1608. if ( in_array( $exp[ 0 ], $from_languages ) ) {
  1609. $lang_pairs[ $exp[ 0 ] ][ $exp[ 1 ] ] = 1;
  1610. }
  1611. }
  1612. }
  1613. $iclsettings[ 'language_pairs' ] = $lang_pairs;
  1614. $this->save_settings( $iclsettings );
  1615. }
  1616. function get_active_languages( $refresh = false )
  1617. {
  1618. global $wpdb, $current_user;
  1619. if ( $refresh || !isset($this->active_languages) || !$this->active_languages ) {
  1620. $current_language = $this->get_current_language();
  1621. if ( defined( 'WP_ADMIN' ) && isset($this->admin_language) && $this->admin_language ) {
  1622. $in_language = $this->admin_language;
  1623. } else {
  1624. $in_language = $current_language ? $current_language : $this->get_default_language();
  1625. }
  1626. if ( !$refresh && isset( $this->icl_language_name_cache ) ) {
  1627. $res = $this->icl_language_name_cache->get( 'in_language_' . $in_language );
  1628. } else {
  1629. $res = null;
  1630. }
  1631. if ( !$res || !is_array( $res ) ) {
  1632. if(!$in_language) {
  1633. $in_language = 'en';
  1634. }
  1635. $res_prepared = $wpdb->prepare( "
  1636. SELECT l.id, code, english_name, active, lt.name AS display_name, l.encode_url, l.default_locale, l.tag
  1637. FROM {$wpdb->prefix}icl_languages l
  1638. JOIN {$wpdb->prefix}icl_languages_translations lt ON l.code=lt.language_code
  1639. WHERE
  1640. active=1 AND lt.display_language_code = %s
  1641. ORDER BY major DESC, english_name ASC", array($in_language));
  1642. $res = $wpdb->get_results( $res_prepared, ARRAY_A );
  1643. if ( isset( $this->icl_language_name_cache ) ) {
  1644. $this->icl_language_name_cache->set( 'in_language_' . $in_language, $res );
  1645. }
  1646. }
  1647. $languages = array();
  1648. if ( $res ) {
  1649. foreach ( $res as $r ) {
  1650. $languages[ $r[ 'code' ] ] = $r;
  1651. }
  1652. }
  1653. if ( isset( $this->icl_language_name_cache ) ) {
  1654. $res = $this->icl_language_name_cache->get( 'languages' );
  1655. } else {
  1656. $res = null;
  1657. }
  1658. //WPML setup
  1659. if ( !isset($this->settings[ 'setup_complete' ]) || empty( $this->settings[ 'setup_complete' ] ) ) {
  1660. $res = null;
  1661. }
  1662. if ( !$res && $languages ) {
  1663. $res = $wpdb->get_results( "
  1664. SELECT language_code, name
  1665. FROM {$wpdb->prefix}icl_languages_translations
  1666. WHERE language_code IN ('" . join( "','", array_keys( $languages ) ) . "') AND language_code = display_language_code
  1667. " );
  1668. if ( isset( $this->icl_language_name_cache ) ) {
  1669. $this->icl_language_name_cache->set( 'languages', $res );
  1670. }
  1671. }
  1672. if($res) {
  1673. foreach ( $res as $row ) {
  1674. $languages[ $row->language_code ][ 'native_name' ] = $row->name;
  1675. }
  1676. $this->active_languages = $languages;
  1677. }
  1678. }
  1679. // hide languages for front end
  1680. if ( !is_admin() && isset( $this->settings[ 'hidden_languages' ]) && !empty( $this->settings[ 'hidden_languages' ] ) && is_array( $this->settings[ 'hidden_languages' ] ) ) {
  1681. if ( !isset( $current_user ) || !$current_user ) {
  1682. get_currentuserinfo();
  1683. }
  1684. if ( empty( $current_user->data ) || !get_user_meta( $this->get_current_user()->ID, 'icl_show_hidden_languages', true ) ) {
  1685. foreach ( $this->settings[ 'hidden_languages' ] as $l ) {
  1686. unset( $this->active_languages[ $l ] );
  1687. }
  1688. }
  1689. }
  1690. return $this->active_languages;
  1691. }
  1692. function order_languages( $languages )
  1693. {
  1694. $ordered_languages = array();
  1695. if ( is_array( $this->settings[ 'languages_order' ] ) ) {
  1696. foreach ( $this->settings[ 'languages_order' ] as $code ) {
  1697. if ( isset( $languages[ $code ] ) ) {
  1698. $ordered_languages[ $code ] = $languages[ $code ];
  1699. unset( $languages[ $code ] );
  1700. }
  1701. }
  1702. } else {
  1703. // initial save
  1704. $iclsettings[ 'languages_order' ] = array_keys( $languages );
  1705. $this->save_settings( $iclsettings );
  1706. }
  1707. if ( !empty( $languages ) ) {
  1708. foreach ( $languages as $code => $lang ) {
  1709. $ordered_languages[ $code ] = $lang;
  1710. }
  1711. }
  1712. return $ordered_languages;
  1713. }
  1714. function set_active_languages( $arr )
  1715. {
  1716. global $wpdb;
  1717. if ( !empty( $arr ) ) {
  1718. $tmp = array();
  1719. foreach ( $arr as $code ) {
  1720. $tmp[ ] = esc_sql( trim( $code ) );
  1721. }
  1722. // set the locale
  1723. $current_active_languages = (array)$wpdb->get_col( "SELECT code FROM {$wpdb->prefix}icl_languages WHERE active = 1" );
  1724. $new_languages = array_diff( $tmp, $current_active_languages );
  1725. if ( !empty( $new_languages ) ) {
  1726. foreach ( $new_languages as $code ) {
  1727. $default_locale_prepared = $wpdb->prepare( "SELECT default_locale FROM {$wpdb->prefix}icl_languages WHERE code=%s", $code );
  1728. $default_locale = $wpdb->get_var( $default_locale_prepared );
  1729. if ( $default_locale ) {
  1730. $code_exists_prepared = $wpdb->prepare( "SELECT code FROM {$wpdb->prefix}icl_locale_map WHERE code=%s", $code );
  1731. $code_exists = $wpdb->get_var( $code_exists_prepared );
  1732. if ( $code_exists ) {
  1733. $wpdb->update( $wpdb->prefix . 'icl_locale_map', array( 'locale' => $default_locale ), array( 'code' => $code ) );
  1734. } else {
  1735. $wpdb->insert( $wpdb->prefix . 'icl_locale_map', array( 'code' => $code, 'locale' => $default_locale ) );
  1736. }
  1737. }
  1738. }
  1739. }
  1740. $codes = '(\'' . join( '\',\'', $tmp ) . '\')';
  1741. $wpdb->update( $wpdb->prefix . 'icl_languages', array( 'active' => 0 ), array( 'active' => '1' ) );
  1742. $wpdb->query( "UPDATE {$wpdb->prefix}icl_languages SET active=1 WHERE code IN {$codes}" );
  1743. $this->icl_language_name_cache->clear();
  1744. }
  1745. $res_prepared = $wpdb->prepare( "
  1746. SELECT code, english_name, active, lt.name AS display_name
  1747. FROM {$wpdb->prefix}icl_languages l
  1748. JOIN {$wpdb->prefix}icl_languages_translations lt ON l.code=lt.language_code
  1749. WHERE
  1750. active=1 AND lt.display_language_code = %s
  1751. ORDER BY major DESC, english_name ASC", $this->get_default_language() );
  1752. $res = $wpdb->get_results( $res_prepared, ARRAY_A );
  1753. $languages = array();
  1754. foreach ( $res as $r ) {
  1755. $languages[ ] = $r;
  1756. }
  1757. $this->active_languages = $languages;
  1758. return true;
  1759. }
  1760. /**
  1761. * @param $lang_code
  1762. * Checks if a given language code belongs to a currently active language.
  1763. * @return bool
  1764. */
  1765. function is_active_language( $lang_code ) {
  1766. $result = false;
  1767. $active_languages = $this->get_active_languages();
  1768. foreach ( $active_languages as $lang ) {
  1769. if ( $lang_code == $lang[ 'code' ] ) {
  1770. $result = true;
  1771. break;
  1772. }
  1773. }
  1774. return $result;
  1775. }
  1776. function get_languages( $lang = false )
  1777. {
  1778. global $wpdb;
  1779. if ( !$lang ) {
  1780. $lang = $this->get_default_language();
  1781. }
  1782. $res_query = "SELECT
  1783. code, english_name, major, active, default_locale, lt.name AS display_name
  1784. FROM {$wpdb->prefix}icl_languages l
  1785. JOIN {$wpdb->prefix}icl_languages_translations lt ON l.code=lt.language_code
  1786. WHERE lt.display_language_code = %s
  1787. ORDER BY major DESC, english_name ASC";
  1788. $res_query_prepared = $wpdb->prepare($res_query, $lang );
  1789. $res = $wpdb->get_results( $res_query_prepared, ARRAY_A );
  1790. $languages = array();
  1791. foreach ( (array)$res as $r ) {
  1792. $languages[ ] = $r;
  1793. }
  1794. return $languages;
  1795. }
  1796. function get_language_details( $code )
  1797. {
  1798. global $wpdb;
  1799. if ( defined( 'WP_ADMIN' ) ) {
  1800. $dcode = $this->admin_language;
  1801. } else {
  1802. $dcode = $code;
  1803. }
  1804. if ( isset( $this->icl_language_name_cache ) ) {
  1805. $details = $this->icl_language_name_cache->get( 'language_details_' . $code . $dcode );
  1806. } else {
  1807. $details = null;
  1808. }
  1809. if ( !$details ) {
  1810. $details = $wpdb->get_row( "
  1811. SELECT
  1812. code, english_name, major, active, lt.name AS display_name
  1813. FROM {$wpdb->prefix}icl_languages l
  1814. JOIN {$wpdb->prefix}icl_languages_translations lt ON l.code=lt.language_code
  1815. WHERE lt.display_language_code = '{$dcode}' AND code='{$code}'
  1816. ORDER BY major DESC, english_name ASC", ARRAY_A );
  1817. if ( isset( $this->icl_language_name_cache ) ) {
  1818. $this->icl_language_name_cache->set( 'language_details_' . $code . $dcode, $details );
  1819. }
  1820. }
  1821. return $details;
  1822. }
  1823. function get_language_code( $english_name )
  1824. {
  1825. global $wpdb;
  1826. $code = $wpdb->get_row( "
  1827. SELECT
  1828. code
  1829. FROM {$wpdb->prefix}icl_languages
  1830. WHERE english_name = '{$english_name}'", ARRAY_A );
  1831. return $code[ 'code' ];
  1832. }
  1833. function get_icl_translator_status( &$iclsettings, $res = null )
  1834. {
  1835. if ( $res == null ) {
  1836. // check what languages we have translators for.
  1837. require_once ICL_PLUGIN_PATH . '/lib/Snoopy.class.php';
  1838. require_once ICL_PLUGIN_PATH . '/lib/xml2array.php';
  1839. require_once ICL_PLUGIN_PATH . '/lib/icl_api.php';
  1840. $icl_query = false;
  1841. if ( empty( $iclsettings[ 'site_id' ] ) ) {
  1842. // Must be for support
  1843. if ( !empty( $iclsettings[ 'support_site_id' ] ) ) {
  1844. $icl_query = new ICanLocalizeQuery( $iclsettings[ 'support_site_id' ], $iclsettings[ 'support_access_key' ] );
  1845. }
  1846. } else {
  1847. $icl_query = new ICanLocalizeQuery( $iclsettings[ 'site_id' ], $iclsettings[ 'access_key' ] );
  1848. }
  1849. if ( $icl_query === false ) {
  1850. return;
  1851. }
  1852. $res = $icl_query->get_website_details();
  1853. }
  1854. if ( isset( $res[ 'translation_languages' ][ 'translation_language' ] ) ) {
  1855. // reset $this->settings['icl_lang_status']
  1856. $iclsettings[ 'icl_lang_status' ] = array();
  1857. $translation_languages = $res[ 'translation_languages' ][ 'translation_language' ];
  1858. if ( !isset( $translation_languages[ 0 ] ) ) {
  1859. $buf = $translation_languages;
  1860. $translation_languages = array( 0 => $buf );
  1861. }
  1862. $target = array();
  1863. foreach ( $translation_languages as $lang ) {
  1864. $translators = $_tr = array();
  1865. $max_rate = false;
  1866. if ( isset( $lang[ 'translators' ] ) && !empty( $lang[ 'translators' ] ) ) {
  1867. if ( !isset( $lang[ 'translators' ][ 'translator' ][ 0 ] ) ) {
  1868. $_tr[ 0 ] = $lang[ 'translators' ][ 'translator' ];
  1869. } else {
  1870. $_tr = $lang[ 'translators' ][ 'translator' ];
  1871. }
  1872. foreach ( $_tr as $t ) {
  1873. if ( $max_rate === false || $t[ 'attr' ][ 'amount' ] > $max_rate ) {
  1874. $max_rate = $t[ 'attr' ][ 'amount' ];
  1875. }
  1876. $translators[ ] = array( 'id' => $t[ 'attr' ][ 'id' ], 'nickname' => $t[ 'attr' ][ 'nickname' ], 'contract_id' => $t[ 'attr' ][ 'contract_id' ] );
  1877. }
  1878. }
  1879. $target[ ] = array(
  1880. 'from' => $this->get_language_code( ICL_Pro_Translation::server_languages_map( $lang[ 'attr' ][ 'from_language_name' ], true ) ),
  1881. 'to' => $this->get_language_code( ICL_Pro_Translation::server_languages_map( $lang[ 'attr' ][ 'to_language_name' ], true ) ), 'have_translators' => $lang[ 'attr' ][ 'have_translators' ],
  1882. 'available_translators' => $lang[ 'attr' ][ 'available_translators' ], 'applications' => $lang[ 'attr' ][ 'applications' ], 'contract_id' => $lang[ 'attr' ][ 'contract_id' ], 'id' => $lang[ 'attr' ][ 'id' ],
  1883. 'translators' => $translators, 'max_rate' => $max_rate
  1884. );
  1885. }
  1886. $iclsettings[ 'icl_lang_status' ] = $target;
  1887. }
  1888. if ( isset( $res[ 'client' ][ 'attr' ] ) ) {
  1889. $iclsettings[ 'icl_balance' ] = $res[ 'client' ][ 'attr' ][ 'balance' ];
  1890. $iclsettings[ 'icl_anonymous_user' ] = $res[ 'client' ][ 'attr' ][ 'anon' ];
  1891. }
  1892. if ( isset( $res[ 'html_status' ][ 'value' ] ) ) {
  1893. $iclsettings[ 'icl_html_status' ] = html_entity_decode( $res[ 'html_status' ][ 'value' ] );
  1894. $iclsettings[ 'icl_html_status' ] = preg_replace_callback(
  1895. '#<a([^>]*)href="([^"]+)"([^>]*)>#i',
  1896. create_function( '$matches', 'global $sitepress; return $sitepress->create_icl_popup_link($matches[2], array(\'unload_cb\'=>\'icl_pt_reload_translation_box\'));' ),
  1897. $iclsettings[ 'icl_html_status' ]
  1898. );
  1899. }
  1900. if ( isset( $res[ 'translators_management_info' ][ 'value' ] ) ) {
  1901. $iclsettings[ 'translators_management_info' ] = html_entity_decode( $res[ 'translators_management_info' ][ 'value' ] );
  1902. $iclsettings[ 'translators_management_info' ] = preg_replace_callback(
  1903. '#<a([^>]*)href="([^"]+)"([^>]*)>#i',
  1904. create_function( '$matches', 'global $sitepress; return $sitepress->create_icl_popup_link($matches[2], array(\'unload_cb\'=>\'icl_pt_reload_translation_box\'));' ),
  1905. $iclsettings[ 'translators_management_info' ]
  1906. );
  1907. }
  1908. $iclsettings[ 'icl_support_ticket_id' ] = @intval( $res[ 'attr' ][ 'support_ticket_id' ] );
  1909. }
  1910. function get_language_status_text( $from_lang, $to_lang, $pop_close_cb = false )
  1911. {
  1912. $pop_args = array( 'title' => 'ICanLocalize' );
  1913. if ( $pop_close_cb ) {
  1914. $pop_args[ 'unload_cb' ] = $pop_close_cb;
  1915. }
  1916. $lang_status = !empty( $this->settings[ 'icl_lang_status' ] ) ? $this->settings[ 'icl_lang_status' ] : array();
  1917. foreach ( $lang_status as $lang ) {
  1918. if ( $from_lang == $lang[ 'from' ] && $to_lang == $lang[ 'to' ] ) {
  1919. if ( isset( $lang[ 'available_translators' ] ) ) {
  1920. if ( !$lang[ 'available_translators' ] ) {
  1921. if ( $this->settings[ 'icl_support_ticket_id' ] == '' ) {
  1922. // No translators available on icanlocalize for this language pair.
  1923. $response = sprintf( __( '- (No translators available - please %sprovide more information about your site%s)', 'sitepress' ), $this->create_icl_popup_link( ICL_API_ENDPOINT . '/websites/' . $this->settings[ 'site_id' ] . '/explain?after=refresh_langs', $pop_args ), '</a>' );
  1924. } else {
  1925. $response = sprintf( __( '- (No translators available - %scheck progress%s)', 'sitepress' ), $this->create_icl_popup_link( ICL_API_ENDPOINT . '/support/show/' . $this->settings[ 'icl_support_ticket_id' ] . '?after=refresh_langs', $pop_args ), '</a>' );
  1926. }
  1927. } else {
  1928. if ( !$lang[ 'applications' ] ) {
  1929. // No translators have applied for this language pair.
  1930. $pop_args[ 'class' ] = 'icl_hot_link';
  1931. $response = ' | ' . $this->create_icl_popup_link( "@select-translators;{$from_lang};{$to_lang}@", $pop_args ) . __( 'Select translators', 'sitepress' ) . '</a>';
  1932. } else {
  1933. if ( !$lang[ 'have_translators' ] ) {
  1934. // translators have applied but none selected yet
  1935. $pop_args[ 'class' ] = 'icl_hot_link';
  1936. $response = ' | ' . $this->create_icl_popup_link( "@select-translators;{$from_lang};{$to_lang}@", $pop_args ) . __( 'Select translators', 'sitepress' ) . '</a>';
  1937. } else {
  1938. // there are translators ready to translate
  1939. $translators = array();
  1940. if ( is_array( $lang[ 'translators' ] ) ) {
  1941. foreach ( $lang[ 'translators' ] as $translator ) {
  1942. $link = $this->create_icl_popup_link( ICL_API_ENDPOINT . '/websites/' . $this->settings[ 'site_id' ] . '/website_translation_offers/' . $lang[ 'id' ] . '/website_translation_contracts/' . $translator[ 'contract_id' ], $pop_args );
  1943. $translators[ ] = $link . esc_html( $translator[ 'nickname' ] ) . '</a>';
  1944. }
  1945. }
  1946. $response = ' | ' . $this->create_icl_popup_link( "@select-translators;{$from_lang};{$to_lang}@", $pop_args ) . __( 'Select translators', 'sitepress' ) . '</a>';
  1947. $response .= ' | ' . sprintf( __( 'Communicate with %s', 'sitepress' ), join( ', ', $translators ) );
  1948. }
  1949. }
  1950. }
  1951. return $response;
  1952. }
  1953. break;
  1954. }
  1955. }
  1956. $pop_args[ 'class' ] = 'icl_hot_link';
  1957. $response = ' | ' . $this->create_icl_popup_link( "@select-translators;{$from_lang};{$to_lang}@", $pop_args ) . __( 'Select translators', 'sitepress' ) . '</a>';
  1958. // no status found
  1959. return $response;
  1960. }
  1961. function are_waiting_for_translators( $from_lang )
  1962. {
  1963. $lang_status = $this->settings[ 'icl_lang_status' ];
  1964. if ( $lang_status && $this->icl_account_configured() ) {
  1965. foreach ( $lang_status as $lang ) {
  1966. if ( $from_lang == $lang[ 'from' ] ) {
  1967. if ( isset( $lang[ 'available_translators' ] ) ) {
  1968. if ( $lang[ 'available_translators' ] && !$lang[ 'applications' ] ) {
  1969. return true;
  1970. }
  1971. }
  1972. }
  1973. }
  1974. }
  1975. return false;
  1976. }
  1977. function get_default_language()
  1978. {
  1979. return isset( $this->settings[ 'default_language' ] ) ? $this->settings[ 'default_language' ] : false;
  1980. }
  1981. function get_current_language()
  1982. {
  1983. return apply_filters( 'icl_current_language', $this->this_lang );
  1984. }
  1985. function get_strings_language()
  1986. {
  1987. return isset( $this->settings[ 'st' ][ 'strings_language' ] ) ? $this->settings[ 'st' ][ 'strings_language' ] : false;
  1988. }
  1989. function switch_lang( $code = null, $cookie_lang = false )
  1990. {
  1991. static $original_language, $original_language_cookie;
  1992. if ( is_null( $original_language ) ) {
  1993. $original_language = $this->get_current_language();
  1994. }
  1995. if ( is_null( $code ) ) {
  1996. $this->this_lang = $original_language;
  1997. $this->admin_language = $original_language;
  1998. // restore cookie language if case
  1999. if ( !empty( $original_language_cookie ) ) {
  2000. $this->update_language_cookie($original_language_cookie);
  2001. $original_language_cookie = false;
  2002. }
  2003. } else {
  2004. if ( $code == 'all' || in_array( $code, array_keys( $this->get_active_languages() ) ) ) {
  2005. $this->this_lang = $code;
  2006. $this->admin_language = $code;
  2007. }
  2008. // override cookie language
  2009. if ( $cookie_lang ) {
  2010. $original_language_cookie = $this->get_language_cookie();
  2011. $this->update_language_cookie($code);
  2012. }
  2013. }
  2014. }
  2015. function set_default_language( $code )
  2016. {
  2017. $previous_default = $this->get_setting('default_language');
  2018. $this->set_setting( 'default_language', $code);
  2019. $this->set_setting('admin_default_language', $code);
  2020. $this->save_settings();
  2021. do_action('icl_after_set_default_language',$code, $previous_default);
  2022. // change WP locale
  2023. $locale = $this->get_locale( $code );
  2024. if ( $locale ) {
  2025. update_option( 'WPLANG', $locale );
  2026. }
  2027. if ( $code != 'en' && !file_exists( ABSPATH . LANGDIR . '/' . $locale . '.mo' ) ) {
  2028. return 1; //locale not installed
  2029. }
  2030. return true;
  2031. }
  2032. function get_icl_translation_enabled( $lang = null, $langto = null )
  2033. {
  2034. if ( !is_null( $lang ) ) {
  2035. if ( !is_null( $langto ) ) {
  2036. return $this->settings[ 'language_pairs' ][ $lang ][ $langto ];
  2037. } else {
  2038. return !empty( $this->settings[ 'language_pairs' ][ $lang ] );
  2039. }
  2040. } else {
  2041. return isset( $this->settings[ 'enable_icl_translations' ] ) ? $this->settings[ 'enable_icl_translations' ] : false;
  2042. }
  2043. }
  2044. function set_icl_translation_enabled()
  2045. {
  2046. $iclsettings[ 'translation_enabled' ] = true;
  2047. $this->save_settings( $iclsettings );
  2048. }
  2049. function icl_account_reqs()
  2050. {
  2051. $errors = array();
  2052. if ( !$this->get_icl_translation_enabled() ) {
  2053. $errors[ ] = __( 'Professional translation not enabled', 'sitepress' );
  2054. }
  2055. return $errors;
  2056. }
  2057. function icl_account_configured()
  2058. {
  2059. return isset( $this->settings[ 'site_id' ] ) && $this->settings[ 'site_id' ] && isset( $this->settings[ 'access_key' ] ) && $this->settings[ 'access_key' ];
  2060. }
  2061. function icl_support_configured()
  2062. {
  2063. return isset( $this->settings[ 'support_site_id' ] ) && isset( $this->settings[ 'support_access_key' ] ) && $this->settings[ 'support_site_id' ] && $this->settings[ 'support_access_key' ];
  2064. }
  2065. function reminders_popup()
  2066. {
  2067. include ICL_PLUGIN_PATH . '/modules/icl-translation/icl-reminder-popup.php';
  2068. exit;
  2069. }
  2070. function create_icl_popup_link( $link, $args = array(), $just_url = false, $support_mode = false )
  2071. {
  2072. // defaults
  2073. /** @var $id int */
  2074. /** @var $class string */
  2075. $defaults = array(
  2076. 'title' => null, 'class' => '', 'id' => '', 'ar' => 0, // auto_resize
  2077. 'unload_cb' => false, // onunload callback
  2078. );
  2079. extract( $defaults );
  2080. extract( $args, EXTR_OVERWRITE );
  2081. if ( !empty( $ar ) ) {
  2082. $auto_resize = '&amp;auto_resize=1';
  2083. } else {
  2084. $auto_resize = '';
  2085. }
  2086. $unload_cb = isset( $unload_cb ) ? '&amp;unload_cb=' . $unload_cb : '';
  2087. $url_glue = false !== strpos( $link, '?' ) ? '&' : '?';
  2088. $link .= $url_glue . 'compact=1';
  2089. if ( isset( $this->settings[ 'access_key' ] ) || isset( $this->settings[ 'support_access_key' ] ) ) {
  2090. if ( $support_mode && isset( $this->settings[ 'support_access_key' ] ) ) {
  2091. $link .= '&accesskey=' . $this->settings[ 'support_access_key' ];
  2092. } elseif ( isset( $this->settings[ 'access_key' ] ) ) {
  2093. $link .= '&accesskey=' . $this->settings[ 'access_key' ];
  2094. }
  2095. }
  2096. if ( !empty( $id ) ) {
  2097. $id = ' id="' . $id . '"';
  2098. }
  2099. if ( isset( $title ) && !$just_url ) {
  2100. return '<a class="icl_thickbox ' . $class . '" title="' . $title . '" href="admin.php?page=' . ICL_PLUGIN_FOLDER . "/menu/languages.php&amp;icl_action=reminder_popup{$auto_resize}{$unload_cb}&amp;target=" . urlencode( $link ) . '"' . $id . '>';
  2101. } else {
  2102. if ( !$just_url ) {
  2103. return '<a class="icl_thickbox ' . $class . '" href="admin.php?page=' . ICL_PLUGIN_FOLDER . "/menu/languages.php&amp;icl_action=reminder_popup{$auto_resize}{$unload_cb}&amp;target=" . urlencode( $link ) . '"' . $id . '>';
  2104. } else {
  2105. return 'admin.php?page=' . ICL_PLUGIN_FOLDER . "/menu/languages.php&amp;icl_action=reminder_popup{$auto_resize}{$unload_cb}&amp;target=" . urlencode( $link );
  2106. }
  2107. }
  2108. }
  2109. function js_scripts_setup()
  2110. {
  2111. //TODO: move javascript to external resource (use wp_localize_script() to pass arguments)
  2112. global $pagenow, $wpdb;
  2113. $default_language = $this->get_default_language();
  2114. $current_language = $this->get_current_language();
  2115. if ( isset( $_GET[ 'page' ] ) ) {
  2116. $page = basename( $_GET[ 'page' ] );
  2117. $page_basename = str_replace( '.php', '', $page );
  2118. } else {
  2119. $page_basename = false;
  2120. }
  2121. $icl_ajax_url_root = rtrim(get_site_url(),'/');
  2122. if(defined('FORCE_SSL_ADMIN') && FORCE_SSL_ADMIN) {
  2123. $icl_ajax_url_root = str_replace('http://', 'https://', $icl_ajax_url_root);
  2124. }
  2125. $icl_ajax_url = $icl_ajax_url_root . '/wp-admin/admin.php?page=' . ICL_PLUGIN_FOLDER . '/menu/languages.php';
  2126. ?>
  2127. <script type="text/javascript">
  2128. // <![CDATA[
  2129. var icl_ajx_url;
  2130. icl_ajx_url = '<?php echo $icl_ajax_url; ?>';
  2131. var icl_ajx_saved = '<?php echo icl_js_escape( __('Data saved','sitepress')); ?>';
  2132. var icl_ajx_error = '<?php echo icl_js_escape( __('Error: data not saved','sitepress')); ?>';
  2133. var icl_default_mark = '<?php echo icl_js_escape(__('default','sitepress')); ?>';
  2134. var icl_this_lang = '<?php echo $this->this_lang ?>';
  2135. var icl_ajxloaderimg_src = '<?php echo ICL_PLUGIN_URL ?>/res/img/ajax-loader.gif';
  2136. 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').'"'));?>';
  2137. // ]]>
  2138. <?php if(!$this->get_setting('ajx_health_checked')): ?>
  2139. addLoadEvent(function () {
  2140. jQuery.ajax({type: "POST", url: icl_ajx_url, data: "icl_ajx_action=health_check", error: function (msg) {
  2141. var icl_initial_language = jQuery('#icl_initial_language');
  2142. if (icl_initial_language.length) {
  2143. icl_initial_language.find('input').attr('disabled', 'disabled');
  2144. }
  2145. jQuery('.wrap').prepend('<div class="error"><p><?php
  2146. echo icl_js_escape(sprintf(__("WPML can't run normally. There is an installation or server configuration problem. %sShow details%s",'sitepress'),
  2147. '<a href="#" onclick="jQuery(this).parent().next().slideToggle()">', '</a>'));
  2148. ?></p><p style="display:none"><?php echo icl_js_escape(__('AJAX Error:', 'sitepress'))?> ' + msg.statusText + ' [' + msg.status + ']<br />URL:' + icl_ajx_url + '</p></div>');
  2149. }});
  2150. });
  2151. <?php endif; ?>
  2152. </script>
  2153. <?php
  2154. if ( 'options-reading.php' == $pagenow ) {
  2155. list( $warn_home, $warn_posts ) = $this->verify_home_and_blog_pages_translations();
  2156. if ( $warn_home || $warn_posts ) {
  2157. ?>
  2158. <script type="text/javascript">
  2159. addLoadEvent(function () {
  2160. jQuery('input[name="show_on_front"]').parent().parent().parent().parent().append('<?php echo str_replace("'","\\'",$warn_home . $warn_posts); ?>');
  2161. });
  2162. </script>
  2163. <?php
  2164. }
  2165. }
  2166. // display correct links on the posts by status break down
  2167. // also fix links to category and tag pages
  2168. if ( ( 'edit.php' == $pagenow || 'edit-pages.php' == $pagenow || 'categories.php' == $pagenow || 'edit-tags.php' == $pagenow ) && $current_language != $default_language ) {
  2169. ?>
  2170. <script type="text/javascript">
  2171. addLoadEvent(function () {
  2172. jQuery('.subsubsub li a').each(function () {
  2173. var h = jQuery(this).attr('href');
  2174. var urlg;
  2175. if (-1 == h.indexOf('?')) urlg = '?'; else urlg = '&';
  2176. jQuery(this).attr('href', h + urlg + 'lang=<?php echo $current_language?>');
  2177. });
  2178. jQuery('.column-categories a, .column-tags a, .column-posts a').each(function () {
  2179. jQuery(this).attr('href', jQuery(this).attr('href') + '&lang=<?php echo $current_language?>');
  2180. });
  2181. });
  2182. </script>
  2183. <?php
  2184. }
  2185. if ( 'edit-tags.php' == $pagenow ) {
  2186. ?>
  2187. <script type="text/javascript">
  2188. addLoadEvent(function () {
  2189. var edit_tag = jQuery('#edittag');
  2190. if (edit_tag.find('[name="_wp_original_http_referer"]').length && edit_tag.find('[name="_wp_http_referer"]').length) {
  2191. edit_tag.find('[name="_wp_original_http_referer"]').val('<?php
  2192. $post_type = isset($_GET['post_type']) ? '&post_type=' . esc_html($_GET['post_type']) : '';
  2193. echo admin_url('edit-tags.php?taxonomy=' . esc_js($_GET['taxonomy']) . '&lang='.$current_language.'&message=3'.$post_type) ?>');
  2194. }
  2195. });
  2196. </script>
  2197. <?php
  2198. }
  2199. if ( 'post-new.php' == $pagenow ) {
  2200. if ( isset( $_GET[ 'trid' ] ) ) {
  2201. $translations = $wpdb->get_col( $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d", $_GET[ 'trid' ] ) );
  2202. remove_filter( 'option_sticky_posts', array( $this, 'option_sticky_posts' ) ); // remove filter used to get language relevant stickies. get them all
  2203. $sticky_posts = get_option( 'sticky_posts' );
  2204. add_filter( 'option_sticky_posts', array( $this, 'option_sticky_posts' ) ); // add filter back
  2205. $is_sticky = false;
  2206. foreach ( $translations as $t ) {
  2207. if ( in_array( $t, $sticky_posts ) ) {
  2208. $is_sticky = true;
  2209. break;
  2210. }
  2211. }
  2212. if ( isset( $_GET[ 'trid' ] ) && ( $this->settings[ 'sync_ping_status' ] || $this->settings[ 'sync_comment_status' ] ) ) {
  2213. $res = $wpdb->get_row( $wpdb->prepare( "SELECT comment_status, ping_status FROM {$wpdb->prefix}icl_translations t
  2214. JOIN {$wpdb->posts} p ON t.element_id = p.ID WHERE t.trid=%d", $_GET[ 'trid' ] ) ); ?>
  2215. <script type="text/javascript">addLoadEvent(function () {
  2216. var comment_status = jQuery('#comment_status');
  2217. var ping_status = jQuery('#ping_status');
  2218. <?php if($this->settings['sync_comment_status']): ?>
  2219. <?php if($res->comment_status == 'open'): ?>
  2220. comment_status.attr('checked', 'checked');
  2221. <?php else: ?>
  2222. comment_status.removeAttr('checked');
  2223. <?php endif; ?>
  2224. <?php endif; ?>
  2225. <?php if($this->settings['sync_ping_status']): ?>
  2226. <?php if($res->ping_status == 'open'): ?>
  2227. ping_status.attr('checked', 'checked');
  2228. <?php else: ?>
  2229. ping_status.removeAttr('checked');
  2230. <?php endif; ?>
  2231. <?php endif; ?>
  2232. });</script><?php
  2233. }
  2234. if ( isset( $_GET[ 'trid' ] ) && $this->settings[ 'sync_private_flag' ] ) {
  2235. if ( 'private' == $wpdb->get_var( $wpdb->prepare( "
  2236. SELECT p.post_status FROM {$wpdb->prefix}icl_translations t
  2237. JOIN {$wpdb->posts} p ON t.element_id = p.ID
  2238. WHERE t.trid=%d AND t.element_type='post_post'
  2239. ", $_GET[ 'trid' ] ) )
  2240. ) {
  2241. ?>
  2242. <script type="text/javascript">addLoadEvent(function () {
  2243. jQuery('#visibility-radio-private').attr('checked', 'checked');
  2244. jQuery('#post-visibility-display').html('<?php echo icl_js_escape(__('Private', 'sitepress')); ?>');
  2245. });
  2246. </script><?php
  2247. }
  2248. }
  2249. if ( isset( $_GET[ 'trid' ] ) && $this->settings[ 'sync_post_taxonomies' ] ) {
  2250. $post_type = isset( $_GET[ 'post_type' ] ) ? $_GET[ 'post_type' ] : 'post';
  2251. $source_lang = isset( $_GET[ 'source_lang' ] ) ? $_GET[ 'source_lang' ] : $default_language;
  2252. $translatable_taxs = $this->get_translatable_taxonomies( true, $post_type );
  2253. $all_taxs = get_object_taxonomies( $post_type );
  2254. $translations = $this->get_element_translations( $_GET[ 'trid' ], 'post_' . $post_type );
  2255. $js = array();
  2256. if ( !empty( $all_taxs ) ) {
  2257. foreach ( $all_taxs as $tax ) {
  2258. $tax_detail = get_taxonomy( $tax );
  2259. $terms = get_the_terms( $translations[ $source_lang ]->element_id, $tax );
  2260. $term_names = array();
  2261. if ( $terms ) {
  2262. foreach ( $terms as $term ) {
  2263. if ( $tax_detail->hierarchical ) {
  2264. if ( in_array( $tax, $translatable_taxs ) ) {
  2265. $term_id = icl_object_id( $term->term_id, $tax, false );
  2266. } else {
  2267. $term_id = $term->term_id;
  2268. }
  2269. $js[ ] = "jQuery('#in-" . $tax . "-" . $term_id . "').attr('checked', 'checked');";
  2270. } else {
  2271. if ( in_array( $tax, $translatable_taxs ) ) {
  2272. $term_id = icl_object_id( $term->term_id, $tax, false );
  2273. if ( $term_id ) {
  2274. $term = get_term_by( 'id', $term_id, $tax );
  2275. $term_names[ ] = esc_js( $term->name );
  2276. }
  2277. } else {
  2278. $term_names[ ] = esc_js( $term->name );
  2279. }
  2280. }
  2281. }
  2282. }
  2283. if ( $term_names ) {
  2284. $js[ ] = "jQuery('#{$tax} .taghint').css('visibility','hidden');";
  2285. $js[ ] = "jQuery('#new-tag-{$tax}').val('" . join( ', ', $term_names ) . "');";
  2286. }
  2287. }
  2288. }
  2289. if ( $js ) {
  2290. echo '<script type="text/javascript">';
  2291. echo PHP_EOL . '// <![CDATA[' . PHP_EOL;
  2292. echo 'addLoadEvent(function(){' . PHP_EOL;
  2293. echo join( PHP_EOL, $js );
  2294. echo PHP_EOL . 'jQuery().ready(function() {
  2295. jQuery(".tagadd").click();
  2296. jQuery(\'html, body\').prop({scrollTop:0});
  2297. jQuery(\'#title\').focus();
  2298. });' . PHP_EOL;
  2299. echo PHP_EOL . '});' . PHP_EOL;
  2300. echo PHP_EOL . '// ]]>' . PHP_EOL;
  2301. echo '</script>';
  2302. }
  2303. }
  2304. // sync custom fields
  2305. if ( !empty( $this->settings[ 'translation-management' ] ) ) {
  2306. foreach ( (array)$this->settings[ 'translation-management' ][ 'custom_fields_translation' ] as $key => $sync_opt ) {
  2307. if ( $sync_opt == 1 ) {
  2308. $copied_cf[ ] = $key;
  2309. }
  2310. }
  2311. }
  2312. if ( !empty( $copied_cf ) ) {
  2313. $source_lang = isset( $_GET[ 'source_lang' ] ) ? $_GET[ 'source_lang' ] : $default_language;
  2314. $lang_details = $this->get_language_details( $source_lang );
  2315. $original_custom = get_post_custom( $translations[ $source_lang ]->element_id );
  2316. $copied_cf = array_intersect( $copied_cf, array_keys( $original_custom ) );
  2317. $copied_cf = apply_filters( 'icl_custom_fields_to_be_copied', $copied_cf, $translations[ $source_lang ]->element_id );
  2318. if ( !empty( $copied_cf ) && ( empty( $this->user_preferences[ 'notices' ] ) || empty( $this->user_preferences[ 'notices' ][ 'hide_custom_fields_copy' ] ) ) ) {
  2319. $ccf_note = '<img src="' . ICL_PLUGIN_URL . '/res/img/alert.png" alt="Notice" width="16" height="16" style="margin-right:8px" />';
  2320. $ccf_note .= '<a class="icl_user_notice_hide" href="#hide_custom_fields_copy" style="float:right;margin-left:20px;">' . __( 'Never show this.', 'sitepress' ) . '</a>';
  2321. $ccf_note .= wp_nonce_field( 'save_user_preferences_nonce', '_icl_nonce_sup', false, false );
  2322. $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' ] );
  2323. $this->admin_notices( $ccf_note, 'error' );
  2324. }
  2325. }
  2326. }
  2327. ?>
  2328. <?php if ( !empty( $is_sticky ) && $this->settings[ 'sync_sticky_flag' ] ): ?>
  2329. <script type="text/javascript">
  2330. addLoadEvent(
  2331. function () {
  2332. jQuery('#sticky').attr('checked', 'checked');
  2333. var post_visibility_display = jQuery('#post-visibility-display');
  2334. post_visibility_display.html(post_visibility_display.html() + ', <?php echo icl_js_escape(__('Sticky', 'sitepress')) ?>');
  2335. });
  2336. </script>
  2337. <?php endif; ?>
  2338. <?php
  2339. }
  2340. if ( 'page-new.php' == $pagenow || ( 'post-new.php' == $pagenow && isset( $_GET[ 'post_type' ] ) ) ) {
  2341. if ( isset( $_GET[ 'trid' ] ) && ( $this->settings[ 'sync_page_template' ] || $this->settings[ 'sync_page_ordering' ] ) ) {
  2342. $res = $wpdb->get_row( $wpdb->prepare( "
  2343. SELECT p.ID, p.menu_order FROM {$wpdb->prefix}icl_translations t
  2344. JOIN {$wpdb->posts} p ON t.element_id = p.ID
  2345. WHERE t.trid=%d AND p.post_type=%s AND t.element_type=%s
  2346. ", $_GET[ 'trid' ], $_GET[ 'post_type' ], 'post_' . $_GET[ 'post_type' ] ) );
  2347. if ( $this->settings[ 'sync_page_ordering' ] ) {
  2348. $menu_order = $res->menu_order;
  2349. } else {
  2350. $menu_order = false;
  2351. }
  2352. if ( $this->settings[ 'sync_page_template' ] ) {
  2353. $page_template = get_post_meta( $res->ID, '_wp_page_template', true );
  2354. } else {
  2355. $page_template = false;
  2356. }
  2357. if ( $menu_order || $page_template ) {
  2358. ?>
  2359. <script type="text/javascript">addLoadEvent(function () { <?php
  2360. if($menu_order){ ?>
  2361. jQuery('#menu_order').val(<?php echo $menu_order ?>);
  2362. <?php }
  2363. if($page_template && 'default' != $page_template){ ?>
  2364. jQuery('#page_template').val('<?php echo $page_template ?>');
  2365. <?php }
  2366. ?>
  2367. });</script><?php
  2368. }
  2369. }
  2370. } elseif ( 'edit-comments.php' == $pagenow || 'index.php' == $pagenow || 'post.php' == $pagenow ) {
  2371. wp_enqueue_script( 'sitepress-' . $page_basename, ICL_PLUGIN_URL . '/res/js/comments-translation.js', array(), ICL_SITEPRESS_VERSION );
  2372. }
  2373. // sync post dates
  2374. if ( icl_is_post_edit() ) {
  2375. // @since 3.1.5
  2376. // Enqueing 'wp-jquery-ui-dialog', just in case it doesn't get automatically enqueued
  2377. wp_enqueue_style( 'wp-jquery-ui-dialog' );
  2378. wp_enqueue_style( 'sitepress-post-edit', ICL_PLUGIN_URL . '/res/css/post-edit.css', array( ), ICL_SITEPRESS_VERSION );
  2379. wp_enqueue_script( 'sitepress-post-edit', ICL_PLUGIN_URL . '/res/js/post-edit.js', array( 'jquery-ui-dialog', 'jquery-ui-autocomplete', 'autosave' ), ICL_SITEPRESS_VERSION );
  2380. if ( $this->settings[ 'sync_post_date' ] ) {
  2381. $post_type = isset( $_GET[ 'post_type' ] ) ? $_GET[ 'post_type' ] : 'post';
  2382. if ( isset( $_GET[ 'trid' ] ) ) {
  2383. $trid = intval( $_GET[ 'trid' ] );
  2384. } else {
  2385. $post_id = @intval( $_GET[ 'post' ] );
  2386. $trid = $this->get_element_trid( $post_id, 'post_' . $post_type );
  2387. }
  2388. $translations = $this->get_element_translations( $trid, 'post_' . $post_type );
  2389. if ( !empty( $translations ) && isset( $translations[ $current_language ] ) && !$translations[ $current_language ]->original ) {
  2390. $source_lang = isset( $_GET[ 'source_lang' ] ) ? $_GET[ 'source_lang' ] : $default_language;
  2391. if ( isset( $translations[ $source_lang ] ) ) {
  2392. $original_date = $wpdb->get_var( $wpdb->prepare( "SELECT post_date FROM {$wpdb->posts} WHERE ID=%d", $translations[ $source_lang ]->element_id ) );
  2393. $exp = explode( ' ', $original_date );
  2394. list( $aa, $mm, $jj ) = explode( '-', $exp[ 0 ] );
  2395. list( $hh, $mn, $ss ) = explode( ':', $exp[ 1 ] );
  2396. ?>
  2397. <script type="text/javascript">
  2398. addLoadEvent(
  2399. function () {
  2400. jQuery('#aa').val('<?php echo $aa ?>').attr('readonly', 'readonly');
  2401. jQuery('#mm').val('<?php echo $mm ?>').attr('readonly', 'readonly');
  2402. jQuery('#jj').val('<?php echo $jj ?>').attr('readonly', 'readonly');
  2403. jQuery('#hh').val('<?php echo $hh ?>').attr('readonly', 'readonly');
  2404. jQuery('#mn').val('<?php echo $mn ?>').attr('readonly', 'readonly');
  2405. jQuery('#ss').val('<?php echo $ss ?>').attr('readonly', 'readonly');
  2406. var timestamp = jQuery('#timestamp');
  2407. timestamp.find('b').html('<?php esc_html_e('copy from original', 'sitepress') ?>');
  2408. timestamp.next().html('<?php esc_html_e('show', 'sitepress') ?>');
  2409. });
  2410. </script>
  2411. <?php
  2412. }
  2413. }
  2414. }
  2415. }
  2416. if ( 'post-new.php' == $pagenow && isset( $_GET[ 'trid' ] ) && $this->settings[ 'sync_post_format' ] && function_exists( 'get_post_format' ) ) {
  2417. $format = get_post_format( $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' ] ) ) );
  2418. ?>
  2419. <script type="text/javascript">
  2420. addLoadEvent(function () {
  2421. jQuery('#post-format-' + '<?php echo $format ?>').attr('checked', 'checked');
  2422. });
  2423. </script><?php
  2424. }
  2425. if ( is_admin() ) {
  2426. wp_enqueue_script( 'thickbox' );
  2427. wp_enqueue_script( 'theme-preview' );
  2428. wp_enqueue_script( 'sitepress-icl_reminders', ICL_PLUGIN_URL . '/res/js/icl_reminders.js', array(), ICL_SITEPRESS_VERSION );
  2429. }
  2430. //if('content-translation' == $page_basename) {
  2431. // wp_enqueue_script('icl-sidebar-scripts', ICL_PLUGIN_URL . '/res/js/icl_sidebar.js', array(), ICL_SITEPRESS_VERSION);
  2432. //}
  2433. if ( 'languages' == $page_basename || 'string-translation' == $page_basename ) {
  2434. wp_enqueue_script( 'colorpicker' );
  2435. wp_enqueue_script( 'jquery-ui-sortable' );
  2436. }
  2437. }
  2438. function js_load()
  2439. {
  2440. if ( is_admin() && !defined( 'DOING_AJAX' ) ) {
  2441. if ( isset( $_GET[ 'page' ] ) ) {
  2442. $page = basename( $_GET[ 'page' ] );
  2443. $page_basename = str_replace( '.php', '', $page );
  2444. } else {
  2445. $page_basename = false;
  2446. }
  2447. if ( isset( $_SERVER[ 'SCRIPT_NAME' ] ) && ( strpos( $_SERVER[ 'SCRIPT_NAME' ], 'post-new.php' ) || strpos( $_SERVER[ 'SCRIPT_NAME' ], 'post.php' ) ) ) {
  2448. wp_register_script( 'sitepress-post-edit-tags', ICL_PLUGIN_URL . '/res/js/post-edit-terms.js', array( 'jquery', 'underscore' ) );
  2449. $post_edit_messages = array(
  2450. 'switch_language_title' => __( 'You are about to change the language of {post_name}.', 'sitepress' ),
  2451. 'switch_language_alert' => __( 'All categories and tags will be translated if possible.', 'sitepress' ),
  2452. 'connection_loss_alert' => __( 'The following terms do not have a translation in the chosen language and will be disconnected from this post:', 'sitepress' ),
  2453. 'loading' => __( 'Loading Language Data for {post_name}', 'sitepress' ),
  2454. 'switch_language_message' => __( 'Please make sure that you\'ve saved all the changes. We will have to reload the page.', 'sitepress' ),
  2455. 'switch_language_confirm' => __( 'Do you want to continue?', 'sitepress' ),
  2456. );
  2457. wp_localize_script( 'sitepress-post-edit-tags', 'icl_post_edit_messages', $post_edit_messages );
  2458. wp_enqueue_script( 'sitepress-post-edit-tags' );
  2459. }
  2460. if ( isset( $_SERVER[ 'SCRIPT_NAME' ] ) && strpos( $_SERVER[ 'SCRIPT_NAME' ], 'edit.php' ) ) {
  2461. wp_register_script( 'sitepress-post-list-quickedit', ICL_PLUGIN_URL . '/res/js/post-list-quickedit.js', array( 'jquery') );
  2462. wp_enqueue_script( 'sitepress-post-list-quickedit' );
  2463. }
  2464. wp_enqueue_script( 'sitepress-scripts', ICL_PLUGIN_URL . '/res/js/scripts.js', array( 'jquery' ), ICL_SITEPRESS_VERSION );
  2465. if ( isset( $page_basename ) && file_exists( ICL_PLUGIN_PATH . '/res/js/' . $page_basename . '.js' ) ) {
  2466. $dependencies = array();
  2467. $localization = false;
  2468. switch ( $page_basename ) {
  2469. case 'languages':
  2470. $dependencies[ ] = 'colorpicker';
  2471. break;
  2472. case 'troubleshooting':
  2473. $dependencies [ ] = 'jquery-ui-dialog';
  2474. $localization = array(
  2475. 'object_name' => 'troubleshooting_strings',
  2476. 'strings' => array(
  2477. 'success_1' => __( "Post type and source language assignment have been fixed for ", 'sitepress' ),
  2478. 'success_2' => __( " elements", 'sitepress' ),
  2479. 'no_problems' => __( "No errors were found in the assignment of post types." ),
  2480. 'suffixesRemoved' => __( "Language suffixes were removed from the selected terms." )
  2481. )
  2482. );
  2483. wp_enqueue_style("wp-jquery-ui-dialog");
  2484. break;
  2485. }
  2486. $handle = 'sitepress-' . $page_basename;
  2487. wp_register_script( $handle, ICL_PLUGIN_URL . '/res/js/' . $page_basename . '.js', $dependencies, ICL_SITEPRESS_VERSION );
  2488. if ( $localization ) {
  2489. wp_localize_script( $handle, $localization[ 'object_name' ], $localization[ 'strings' ] );
  2490. }
  2491. wp_enqueue_script( $handle );
  2492. } else {
  2493. wp_enqueue_script( 'translate-taxonomy', ICL_PLUGIN_URL . '/res/js/taxonomy-translation.js', array( 'jquery' ), ICL_SITEPRESS_VERSION );
  2494. }
  2495. if ( !wp_style_is( 'toolset-font-awesome', 'registered' ) ) { // check if styles are already registered
  2496. wp_register_style( 'toolset-font-awesome', ICL_PLUGIN_URL . '/res/css/font-awesome.min.css', null, ICL_SITEPRESS_VERSION ); // register if not
  2497. }
  2498. wp_enqueue_style( 'toolset-font-awesome' ); // enqueue styles
  2499. }
  2500. }
  2501. function front_end_js()
  2502. {
  2503. if ( defined( 'ICL_DONT_LOAD_LANGUAGES_JS' ) && ICL_DONT_LOAD_LANGUAGES_JS ) {
  2504. return;
  2505. }
  2506. wp_register_script( 'sitepress', ICL_PLUGIN_URL . '/res/js/sitepress.js', false );
  2507. wp_enqueue_script( 'sitepress' );
  2508. $vars = array(
  2509. 'current_language' => $this->this_lang, 'icl_home' => $this->language_url(),
  2510. );
  2511. wp_localize_script( 'sitepress', 'icl_vars', $vars );
  2512. }
  2513. function js_scripts_categories()
  2514. {
  2515. wp_enqueue_script( 'sitepress-categories', ICL_PLUGIN_URL . '/res/js/categories.js', array(), ICL_SITEPRESS_VERSION );
  2516. }
  2517. function js_scripts_tags()
  2518. {
  2519. wp_enqueue_script( 'sitepress-tags', ICL_PLUGIN_URL . '/res/js/tags.js', array(), ICL_SITEPRESS_VERSION );
  2520. }
  2521. function rtl_fix()
  2522. {
  2523. global $wp_styles;
  2524. if ( !empty( $wp_styles ) && $this->is_rtl() ) {
  2525. $wp_styles->text_direction = 'rtl';
  2526. }
  2527. }
  2528. function css_setup()
  2529. {
  2530. if ( isset( $_GET[ 'page' ] ) ) {
  2531. $page = basename( $_GET[ 'page' ] );
  2532. $page_basename = str_replace( '.php', '', $page );
  2533. }
  2534. wp_enqueue_style( 'sitepress-style', ICL_PLUGIN_URL . '/res/css/style.css', array(), ICL_SITEPRESS_VERSION );
  2535. if ( isset( $page_basename ) && file_exists( ICL_PLUGIN_PATH . '/res/css/' . $page_basename . '.css' ) ) {
  2536. wp_enqueue_style( 'sitepress-' . $page_basename, ICL_PLUGIN_URL . '/res/css/' . $page_basename . '.css', array(), ICL_SITEPRESS_VERSION );
  2537. }
  2538. if ( is_admin() ) {
  2539. wp_enqueue_style( 'thickbox' );
  2540. wp_enqueue_style( 'translate-taxonomy', ICL_PLUGIN_URL . '/res/css/taxonomy-translation.css', array(), ICL_SITEPRESS_VERSION );
  2541. }
  2542. }
  2543. function transfer_icl_account( $create_account_and_transfer )
  2544. {
  2545. $user = $_POST[ 'user' ];
  2546. $user[ 'site_id' ] = $this->settings[ 'site_id' ];
  2547. $user[ 'accesskey' ] = $this->settings[ 'access_key' ];
  2548. $user[ 'create_account' ] = $create_account_and_transfer ? '1' : '0';
  2549. $icl_query = new ICanLocalizeQuery();
  2550. list( $success, $access_key ) = $icl_query->transfer_account( $user );
  2551. if ( $success ) {
  2552. $this->settings[ 'access_key' ] = $access_key;
  2553. // set the support data the same.
  2554. $this->settings[ 'support_access_key' ] = $access_key;
  2555. $this->save_settings();
  2556. return true;
  2557. } else {
  2558. $_POST[ 'icl_form_errors' ] = $access_key;
  2559. return false;
  2560. }
  2561. }
  2562. function process_forms()
  2563. {
  2564. global $wpdb;
  2565. require_once ICL_PLUGIN_PATH . '/lib/Snoopy.class.php';
  2566. require_once ICL_PLUGIN_PATH . '/lib/xml2array.php';
  2567. require_once ICL_PLUGIN_PATH . '/lib/icl_api.php';
  2568. if ( isset( $_POST[ 'icl_post_action' ] ) ) {
  2569. switch ( $_POST[ 'icl_post_action' ] ) {
  2570. case 'save_theme_localization':
  2571. $locales = array();
  2572. foreach ( $_POST as $k => $v ) {
  2573. if ( 0 !== strpos( $k, 'locale_file_name_' ) || !trim( $v ) ) {
  2574. continue;
  2575. }
  2576. $locales[ str_replace( 'locale_file_name_', '', $k ) ] = $v;
  2577. }
  2578. if ( !empty( $locales ) ) {
  2579. $this->set_locale_file_names( $locales );
  2580. }
  2581. break;
  2582. }
  2583. return;
  2584. }
  2585. $create_account = isset( $_POST[ 'icl_create_account_nonce' ] ) && $_POST[ 'icl_create_account_nonce' ] == wp_create_nonce( 'icl_create_account' );
  2586. $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' );
  2587. $config_account = isset( $_POST[ 'icl_configure_account_nonce' ] ) && $_POST[ 'icl_configure_account_nonce' ] == wp_create_nonce( 'icl_configure_account' );
  2588. $create_support_account = isset( $_POST[ 'icl_create_support_account_nonce' ] ) && $_POST[ 'icl_create_support_account_nonce' ] == wp_create_nonce( 'icl_create_support_account' );
  2589. $config_support_account = isset( $_POST[ 'icl_configure_support_account_nonce' ] ) && $_POST[ 'icl_configure_support_account_nonce' ] == wp_create_nonce( 'icl_configure_support_account' );
  2590. $use_existing_account = isset( $_POST[ 'icl_use_account_nonce' ] ) && $_POST[ 'icl_use_account_nonce' ] == wp_create_nonce( 'icl_use_account' );
  2591. $transfer_to_account = isset( $_POST[ 'icl_transfer_account_nonce' ] ) && $_POST[ 'icl_transfer_account_nonce' ] == wp_create_nonce( 'icl_transfer_account' );
  2592. if ( $create_account || $config_account || $create_support_account || $config_support_account ) {
  2593. if ( isset( $_POST[ 'icl_content_trans_setup_back_2' ] ) ) {
  2594. // back button in wizard mode.
  2595. $this->settings[ 'content_translation_setup_wizard_step' ] = 2;
  2596. $this->save_settings();
  2597. } else {
  2598. $user = $_POST[ 'user' ];
  2599. $user[ 'create_account' ] = ( isset( $_POST[ 'icl_create_account_nonce' ] ) || isset( $_POST[ 'icl_create_support_account_nonce' ] ) ) ? 1 : 0;
  2600. $user[ 'platform_kind' ] = 2;
  2601. $user[ 'cms_kind' ] = 1;
  2602. $user[ 'blogid' ] = $wpdb->blogid ? $wpdb->blogid : 1;
  2603. $user[ 'url' ] = get_home_url();
  2604. $user[ 'title' ] = get_option( 'blogname' );
  2605. $user[ 'description' ] = $this->settings[ 'icl_site_description' ];
  2606. $user[ 'is_verified' ] = 1;
  2607. if ( $user[ 'create_account' ] && defined( 'ICL_AFFILIATE_ID' ) && defined( 'ICL_AFFILIATE_KEY' ) ) {
  2608. $user[ 'affiliate_id' ] = ICL_AFFILIATE_ID;
  2609. $user[ 'affiliate_key' ] = ICL_AFFILIATE_KEY;
  2610. }
  2611. $user[ 'interview_translators' ] = $this->settings[ 'interview_translators' ];
  2612. $user[ 'project_kind' ] = $this->settings[ 'website_kind' ];
  2613. /*
  2614. if(is_null($user['project_kind']) || $user['project_kind']==''){
  2615. $_POST['icl_form_errors'] = __('Please select the kind of website','sitepress');
  2616. return;
  2617. }
  2618. */
  2619. $user[ 'pickup_type' ] = intval( $this->settings[ 'translation_pickup_method' ] );
  2620. $notifications = 0;
  2621. if ( $this->settings[ 'icl_notify_complete' ] ) {
  2622. $notifications += 1;
  2623. }
  2624. if ( $this->settings[ 'alert_delay' ] ) {
  2625. $notifications += 2;
  2626. }
  2627. $user[ 'notifications' ] = $notifications;
  2628. // prepare language pairs
  2629. $pay_per_use = $this->settings[ 'translator_choice' ] == 1;
  2630. $language_pairs = $this->settings[ 'language_pairs' ];
  2631. $lang_pairs = array();
  2632. if ( isset( $language_pairs ) ) {
  2633. foreach ( $language_pairs as $k => $v ) {
  2634. $english_fr = $wpdb->get_var( "SELECT english_name FROM {$wpdb->prefix}icl_languages WHERE code='{$k}' " );
  2635. $pay_per_use_increment = 0;
  2636. foreach ( $v as $k => $v ) {
  2637. $pay_per_use_increment++;
  2638. $english_to = $wpdb->get_var( "SELECT english_name FROM {$wpdb->prefix}icl_languages WHERE code='{$k}' " );
  2639. $lang_pairs[ 'from_language' . $pay_per_use_increment ] = ICL_Pro_Translation::server_languages_map( $english_fr );
  2640. $lang_pairs[ 'to_language' . $pay_per_use_increment ] = ICL_Pro_Translation::server_languages_map( $english_to );
  2641. if ( $pay_per_use ) {
  2642. $lang_pairs[ 'pay_per_use' . $pay_per_use_increment ] = 1;
  2643. }
  2644. }
  2645. }
  2646. }
  2647. $icl_query = new ICanLocalizeQuery();
  2648. list( $site_id, $access_key ) = $icl_query->createAccount( array_merge( $user, $lang_pairs ) );
  2649. if ( !$site_id ) {
  2650. $user[ 'pickup_type' ] = ICL_PRO_TRANSLATION_PICKUP_POLLING;
  2651. list( $site_id, $access_key ) = $icl_query->createAccount( array_merge( $user, $lang_pairs ) );
  2652. }
  2653. if ( !$site_id ) {
  2654. if ( $access_key ) {
  2655. $_POST[ 'icl_form_errors' ] = $access_key;
  2656. } else {
  2657. $_POST[ 'icl_form_errors' ] = __( 'An unknown error has occurred when communicating with the ICanLocalize server. Please try again.', 'sitepress' );
  2658. // We will force the next try to be http.
  2659. update_option( '_force_mp_post_http', 1 );
  2660. }
  2661. } else {
  2662. if ( $create_account || $config_account ) {
  2663. $iclsettings[ 'site_id' ] = $site_id;
  2664. $iclsettings[ 'access_key' ] = $access_key;
  2665. $iclsettings[ 'icl_account_email' ] = $user[ 'email' ];
  2666. // set the support data the same.
  2667. $iclsettings[ 'support_site_id' ] = $site_id;
  2668. $iclsettings[ 'support_access_key' ] = $access_key;
  2669. $iclsettings[ 'support_icl_account_email' ] = $user[ 'email' ];
  2670. } else {
  2671. $iclsettings[ 'support_site_id' ] = $site_id;
  2672. $iclsettings[ 'support_access_key' ] = $access_key;
  2673. $iclsettings[ 'support_icl_account_email' ] = $user[ 'email' ];
  2674. }
  2675. if ( isset( $user[ 'pickup_type' ] ) && $user[ 'pickup_type' ] == ICL_PRO_TRANSLATION_PICKUP_POLLING ) {
  2676. $iclsettings[ 'translation_pickup_method' ] = ICL_PRO_TRANSLATION_PICKUP_POLLING;
  2677. }
  2678. $this->save_settings( $iclsettings );
  2679. if ( $user[ 'create_account' ] == 1 ) {
  2680. $_POST[ 'icl_form_success' ] = __( 'A project on ICanLocalize has been created.', 'sitepress' ) . '<br />';
  2681. } else {
  2682. $_POST[ 'icl_form_success' ] = __( 'Project added', 'sitepress' );
  2683. }
  2684. $this->get_icl_translator_status( $iclsettings );
  2685. $this->save_settings( $iclsettings );
  2686. }
  2687. if ( !$create_support_account && !$config_support_account && intval( $site_id ) > 0 && $access_key && $this->settings[ 'content_translation_setup_complete' ] == 0 && $this->settings[ 'content_translation_setup_wizard_step' ] == 3 && !isset( $_POST[ 'icl_form_errors' ] ) ) {
  2688. // we are running the wizard, so we can finish it now.
  2689. $this->settings[ 'content_translation_setup_complete' ] = 1;
  2690. $this->settings[ 'content_translation_setup_wizard_step' ] = 0;
  2691. $this->save_settings();
  2692. }
  2693. }
  2694. } elseif ( $use_existing_account || $transfer_to_account || $create_account_and_transfer ) {
  2695. if ( isset( $_POST[ 'icl_content_trans_setup_back_2' ] ) ) {
  2696. // back button in wizard mode.
  2697. $this->settings[ 'content_translation_setup_wizard_step' ] = 2;
  2698. $this->save_settings();
  2699. } else {
  2700. if ( $transfer_to_account ) {
  2701. $_POST[ 'user' ][ 'email' ] = $_POST[ 'user' ][ 'email2' ];
  2702. }
  2703. // we will be using the support account for the icl_account
  2704. $this->settings[ 'site_id' ] = $this->settings[ 'support_site_id' ];
  2705. $this->settings[ 'access_key' ] = $this->settings[ 'support_access_key' ];
  2706. $this->settings[ 'icl_account_email' ] = $this->settings[ 'support_icl_account_email' ];
  2707. $this->save_settings();
  2708. if ( $transfer_to_account || $create_account_and_transfer ) {
  2709. if ( !$this->transfer_icl_account( $create_account_and_transfer ) ) {
  2710. return;
  2711. }
  2712. }
  2713. // we are running the wizard, so we can finish it now.
  2714. $this->settings[ 'content_translation_setup_complete' ] = 1;
  2715. $this->settings[ 'content_translation_setup_wizard_step' ] = 0;
  2716. $this->save_settings();
  2717. $iclsettings[ 'site_id' ] = $this->settings[ 'site_id' ];
  2718. $iclsettings[ 'access_key' ] = $this->settings[ 'access_key' ];
  2719. $this->get_icl_translator_status( $iclsettings );
  2720. $this->save_settings( $iclsettings );
  2721. }
  2722. } elseif ( isset( $_POST[ 'icl_initial_languagenonce' ] ) && $_POST[ 'icl_initial_languagenonce' ] == wp_create_nonce( 'icl_initial_language' ) ) {
  2723. $this->prepopulate_translations( $_POST[ 'icl_initial_language_code' ] );
  2724. $wpdb->update( $wpdb->prefix . 'icl_languages', array( 'active' => '1' ), array( 'code' => $_POST[ 'icl_initial_language_code' ] ) );
  2725. $blog_default_cat = get_option( 'default_category' );
  2726. $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'" );
  2727. if ( isset( $_POST[ 'save_one_language' ] ) ) {
  2728. $this->settings[ 'setup_wizard_step' ] = 0;
  2729. $this->settings[ 'setup_complete' ] = 1;
  2730. } else {
  2731. $this->settings[ 'setup_wizard_step' ] = 2;
  2732. }
  2733. $this->settings[ 'default_categories' ] = array( $_POST[ 'icl_initial_language_code' ] => $blog_default_cat_tax_id );
  2734. $this->settings[ 'existing_content_language_verified' ] = 1;
  2735. $this->settings[ 'default_language' ] = $_POST[ 'icl_initial_language_code' ];
  2736. $this->settings[ 'admin_default_language' ] = $this->admin_language = $_POST[ 'icl_initial_language_code' ];
  2737. // set the locale in the icl_locale_map (if it's not set)
  2738. $q = "SELECT code FROM {$wpdb->prefix}icl_locale_map WHERE code=%s";
  2739. $q_prepared = $wpdb->prepare($q, $_POST['icl_initial_language_code']);
  2740. if ( !$wpdb->get_var( $q_prepared ) ) {
  2741. $q = "SELECT default_locale FROM {$wpdb->prefix}icl_languages WHERE code=%s";
  2742. $q_prepared = $wpdb->prepare($q, $_POST['icl_initial_language_code']);
  2743. $default_locale = $wpdb->get_var( $q_prepared );
  2744. if ( $default_locale ) {
  2745. $wpdb->insert( $wpdb->prefix . 'icl_locale_map', array( 'code' => $_POST[ 'icl_initial_language_code' ], 'locale' => $default_locale ) );
  2746. }
  2747. }
  2748. $this->save_settings();
  2749. global $sitepress_settings;
  2750. $sitepress_settings = $this->settings;
  2751. $this->get_active_languages( true ); //refresh active languages list
  2752. do_action( 'icl_initial_language_set' );
  2753. } elseif ( isset( $_POST[ 'icl_language_pairs_formnounce' ] ) && $_POST[ 'icl_language_pairs_formnounce' ] == wp_create_nonce( 'icl_language_pairs_form' ) ) {
  2754. $this->save_language_pairs();
  2755. $this->settings[ 'content_translation_languages_setup' ] = 1;
  2756. // Move onto the site description page
  2757. $this->settings[ 'content_translation_setup_wizard_step' ] = 2;
  2758. $this->settings[ 'website_kind' ] = 2;
  2759. $this->settings[ 'interview_translators' ] = 1;
  2760. $this->save_settings();
  2761. } elseif ( isset( $_POST[ 'icl_site_description_wizardnounce' ] ) && $_POST[ 'icl_site_description_wizardnounce' ] == wp_create_nonce( 'icl_site_description_wizard' ) ) {
  2762. if ( isset( $_POST[ 'icl_content_trans_setup_back_2' ] ) ) {
  2763. // back button.
  2764. $this->settings[ 'content_translation_languages_setup' ] = 0;
  2765. $this->settings[ 'content_translation_setup_wizard_step' ] = 1;
  2766. $this->save_settings();
  2767. } elseif ( isset( $_POST[ 'icl_content_trans_setup_next_2' ] ) || isset( $_POST[ 'icl_content_trans_setup_next_2_enter' ] ) ) {
  2768. // next button.
  2769. $description = $_POST[ 'icl_description' ];
  2770. if ( $description == "" ) {
  2771. $_POST[ 'icl_form_errors' ] = __( 'Please provide a short description of the website so that translators know what background is required from them.', 'sitepress' );
  2772. } else {
  2773. $this->settings[ 'icl_site_description' ] = $description;
  2774. $this->settings[ 'content_translation_setup_wizard_step' ] = 3;
  2775. $this->save_settings();
  2776. }
  2777. }
  2778. }
  2779. }
  2780. function prepopulate_translations( $lang )
  2781. {
  2782. global $wpdb;
  2783. if ( !empty( $this->settings[ 'existing_content_language_verified' ] ) ) {
  2784. return;
  2785. }
  2786. $this->icl_translations_cache->clear();
  2787. // case of icl_sitepress_settings accidentally lost
  2788. // if there's at least one translation do not initialize the languages for elements
  2789. $one_translation = $wpdb->get_var( $wpdb->prepare( "SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE language_code<>%s", $lang ) );
  2790. if ( $one_translation ) {
  2791. return;
  2792. }
  2793. $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}icl_translations" );
  2794. $wpdb->query( $wpdb->prepare("
  2795. INSERT INTO {$wpdb->prefix}icl_translations(element_type, element_id, trid, language_code, source_language_code)
  2796. SELECT CONCAT('post_',post_type), ID, ID, %s, NULL FROM {$wpdb->posts} WHERE post_status IN ('draft', 'publish','schedule','future','private', 'pending')
  2797. ", $lang) );
  2798. $maxtrid = 1 + $wpdb->get_var( "SELECT MAX(trid) FROM {$wpdb->prefix}icl_translations" );
  2799. global $wp_taxonomies;
  2800. $taxonomies = array_keys( (array)$wp_taxonomies );
  2801. foreach ( $taxonomies as $tax ) {
  2802. $wpdb->query( $wpdb->prepare("
  2803. INSERT INTO {$wpdb->prefix}icl_translations(element_type, element_id, trid, language_code, source_language_code)
  2804. SELECT 'tax_" . $tax . "', term_taxonomy_id, {$maxtrid}+term_taxonomy_id, %s, NULL FROM {$wpdb->term_taxonomy} WHERE taxonomy = %s
  2805. ", $lang, $tax) );
  2806. $maxtrid = 1 + $wpdb->get_var( "SELECT MAX(trid) FROM {$wpdb->prefix}icl_translations" );
  2807. }
  2808. $wpdb->query( $wpdb->prepare( "
  2809. INSERT INTO {$wpdb->prefix}icl_translations(element_type, element_id, trid, language_code, source_language_code)
  2810. SELECT 'comment', comment_ID, {$maxtrid}+comment_ID, %s, NULL FROM {$wpdb->comments}
  2811. ", $lang) );
  2812. }
  2813. function post_edit_language_options()
  2814. {
  2815. global $post, $iclTranslationManagement, $post_new_file, $post_type_object;
  2816. if(!isset($post) || !$this->settings['setup_complete']) return;
  2817. if ( !function_exists( 'post_type_supports' ) || post_type_supports( $post->post_type, 'editor' ) ) {
  2818. add_action( 'icl_post_languages_options_after', array( $this, 'copy_from_original' ) );
  2819. }
  2820. if ( current_user_can( 'manage_options' ) ) {
  2821. add_meta_box( 'icl_div_config', __( 'Multilingual Content Setup', 'sitepress' ), array( $this, 'meta_box_config' ), $post->post_type, 'normal', 'low' );
  2822. }
  2823. if ( isset( $_POST[ 'icl_action' ] ) && $_POST[ 'icl_action' ] == 'icl_mcs_inline' ) {
  2824. if ( !in_array( $_POST[ 'custom_post' ], array( 'post', 'page' ) ) ) {
  2825. $iclsettings[ 'custom_posts_sync_option' ][ $_POST[ 'custom_post' ] ] = @intval( $_POST[ 'translate' ] );
  2826. if ( @intval( $_POST[ 'translate' ] ) ) {
  2827. $this->verify_post_translations( $_POST[ 'custom_post' ] );
  2828. }
  2829. }
  2830. if ( !empty( $_POST[ 'custom_taxs_off' ] ) ) {
  2831. foreach ( $_POST[ 'custom_taxs_off' ] as $off ) {
  2832. $iclsettings[ 'taxonomies_sync_option' ][ $off ] = 0;
  2833. }
  2834. }
  2835. if ( !empty( $_POST[ 'custom_taxs_on' ] ) ) {
  2836. foreach ( $_POST[ 'custom_taxs_on' ] as $on ) {
  2837. $iclsettings[ 'taxonomies_sync_option' ][ $on ] = 1;
  2838. $this->verify_taxonomy_translations( $on );
  2839. }
  2840. }
  2841. if ( !empty( $_POST[ 'cfnames' ] ) ) {
  2842. foreach ( $_POST[ 'cfnames' ] as $k => $v ) {
  2843. $custom_field_name = base64_decode( $v );
  2844. $iclTranslationManagement->settings[ 'custom_fields_translation' ][ $custom_field_name ] = @intval( $_POST[ 'cfvals' ][ $k ] );
  2845. $iclTranslationManagement->save_settings();
  2846. // sync the custom fields for the current post
  2847. if ( 1 == @intval( $_POST[ 'cfvals' ][ $k ] ) ) {
  2848. $trid = $this->get_element_trid( $_POST[ 'post_id' ], 'post_' . $_POST[ 'custom_post' ] );
  2849. $translations = $this->get_element_translations( $trid, 'post_' . $_POST[ 'custom_post' ] );
  2850. // determine original post id
  2851. $original_post_id = false;
  2852. foreach ( $translations as $t ) {
  2853. if ( $t->original ) {
  2854. $original_post_id = $t->element_id;
  2855. break;
  2856. }
  2857. }
  2858. // get a list of $custom_field_name values that the original document has
  2859. $custom_fields_copy = get_post_meta( $original_post_id, $custom_field_name );
  2860. foreach ( $translations as $t ) {
  2861. if ( $t->original ) {
  2862. continue;
  2863. }
  2864. // if none, then attempt to delete any that the tranlations would have
  2865. if ( empty( $custom_fields_copy ) ) {
  2866. delete_post_meta( $t->element_id, $custom_field_name );
  2867. } else {
  2868. // get a list of $custom_field_name values that the translated document has
  2869. $translation_cfs = get_post_meta( $t->element_id, $custom_field_name );
  2870. // see what elements have been deleted in the original document
  2871. $deleted_fields = $translation_cfs;
  2872. foreach ( $custom_fields_copy as $cfc ) {
  2873. $tc_key = array_search( $cfc, $translation_cfs );
  2874. if ( $tc_key !== false ) {
  2875. unset( $deleted_fields[ $tc_key ] );
  2876. }
  2877. }
  2878. if ( !empty( $deleted_fields ) ) {
  2879. foreach ( $deleted_fields as $meta_value ) {
  2880. delete_post_meta( $t->element_id, $custom_field_name, $meta_value );
  2881. }
  2882. }
  2883. // update each custom field in the translated document
  2884. foreach ( $custom_fields_copy as $meta_value ) {
  2885. if ( !in_array( $meta_value, $translation_cfs ) ) {
  2886. // if it doesn't exist, add
  2887. add_post_meta( $t->element_id, $custom_field_name, $meta_value );
  2888. }
  2889. }
  2890. }
  2891. }
  2892. }
  2893. }
  2894. }
  2895. if ( !empty( $iclsettings ) ) {
  2896. $this->save_settings( $iclsettings );
  2897. }
  2898. }
  2899. $post_types = array_keys( $this->get_translatable_documents() );
  2900. if ( in_array( $post->post_type, $post_types ) ) {
  2901. add_meta_box( 'icl_div', __( 'Language', 'sitepress' ), array( $this, 'meta_box' ), $post->post_type, 'side', 'high' );
  2902. }
  2903. //Fix the "Add new" button adding the language argument, so to create new content in the same language
  2904. if(isset($post_new_file) && isset($post_type_object) && $this->is_translated_post_type($post_type_object->name)) {
  2905. $post_language = $this->get_language_for_element($post->ID, 'post_' . $post_type_object->name);
  2906. $post_new_file = add_query_arg(array('lang' => $post_language), $post_new_file);
  2907. }
  2908. }
  2909. /**
  2910. * @param int $el_id
  2911. * @param string $el_type
  2912. * @param int $trid
  2913. * @param string $language_code
  2914. * @param null|string $src_language_code
  2915. * @param bool $check_duplicates
  2916. *
  2917. * @return bool|int|null|string
  2918. */
  2919. function set_element_language_details( $el_id, $el_type = 'post_post', $trid, $language_code, $src_language_code = null, $check_duplicates = true )
  2920. {
  2921. global $wpdb;
  2922. // Do not set language for the front page, if defined
  2923. $is_root_page = isset( $this->settings[ 'urls' ][ 'root_page' ] ) && $this->settings[ 'urls' ][ 'root_page' ] != 0 && $this->settings[ 'urls' ][ 'root_page' ] == $el_id;
  2924. if ( $is_root_page ) {
  2925. $trid = $this->get_element_trid($el_id, $el_type);
  2926. if($trid) {
  2927. $this->delete_element_translation($trid, $el_type);
  2928. }
  2929. return false;
  2930. }
  2931. // special case for posts and taxonomies
  2932. // check if a different record exists for the same ID
  2933. // if it exists don't save the new element and get out
  2934. if ( $check_duplicates && $el_id ) {
  2935. $exp = explode( '_', $el_type );
  2936. $_type = $exp[ 0 ];
  2937. if ( in_array( $_type, array( 'post', 'tax' ) ) ) {
  2938. $_el_exists = $wpdb->get_var( "
  2939. SELECT translation_id FROM {$wpdb->prefix}icl_translations
  2940. WHERE element_id={$el_id} AND element_type <> '{$el_type}' AND element_type LIKE '{$_type}\\_%'" );
  2941. if ( $_el_exists ) {
  2942. trigger_error( 'Element ID already exists with a different type', E_USER_NOTICE );
  2943. return false;
  2944. }
  2945. }
  2946. }
  2947. if ( $trid ) { // it's a translation of an existing element
  2948. // check whether we have an orphan translation - the same trid and language but a different element id
  2949. $translation_id = $wpdb->get_var( "
  2950. SELECT translation_id FROM {$wpdb->prefix}icl_translations
  2951. WHERE trid = '{$trid}'
  2952. AND language_code = '{$language_code}'
  2953. AND element_id <> '{$el_id}'
  2954. AND source_language_code IS NOT NULL
  2955. " );
  2956. if ( $translation_id ) {
  2957. $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}icl_translations WHERE translation_id=%d", $translation_id ) );
  2958. $this->icl_translations_cache->clear();
  2959. }
  2960. if ( !is_null( $el_id ) && $translation_id = $wpdb->get_var( "SELECT translation_id FROM {$wpdb->prefix}icl_translations
  2961. WHERE element_type='{$el_type}' AND element_id='{$el_id}' AND trid='{$trid}' AND element_id IS NOT NULL" )
  2962. ) {
  2963. //case of language change
  2964. $wpdb->update( $wpdb->prefix . 'icl_translations', array( 'language_code' => $language_code ), array( 'translation_id' => $translation_id ) );
  2965. } elseif ( !is_null( $el_id ) && $translation_id = $wpdb->get_var( "SELECT translation_id FROM {$wpdb->prefix}icl_translations
  2966. WHERE element_type='{$el_type}' AND element_id='{$el_id}' AND element_id IS NOT NULL " )
  2967. ) {
  2968. //case of changing the "translation of"
  2969. if ( empty( $src_language_code ) ) {
  2970. $src_language_code = $wpdb->get_var( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE trid={$trid} AND source_language_code IS NULL" );
  2971. }
  2972. $wpdb->update( $wpdb->prefix . 'icl_translations', array( 'trid' => $trid, 'language_code' => $language_code, 'source_language_code' => $src_language_code ), array( 'element_type' => $el_type, 'element_id' => $el_id ) );
  2973. $this->icl_translations_cache->clear();
  2974. } elseif ( $translation_id = $wpdb->get_var( $wpdb->prepare( "
  2975. SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND language_code='%s' AND element_id IS NULL", $trid, $language_code ) )
  2976. ) {
  2977. $wpdb->update( $wpdb->prefix . 'icl_translations', array( 'element_id' => $el_id ), array( 'translation_id' => $translation_id ) );
  2978. } else {
  2979. //get source
  2980. if ( empty( $src_language_code ) ) {
  2981. $src_language_code = $wpdb->get_var( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE trid={$trid} AND source_language_code IS NULL" );
  2982. }
  2983. // case of adding a new language
  2984. $new = array(
  2985. 'trid' => $trid, 'element_type' => $el_type, 'language_code' => $language_code, 'source_language_code' => $src_language_code
  2986. );
  2987. if ( $el_id ) {
  2988. $new[ 'element_id' ] = $el_id;
  2989. }
  2990. $wpdb->insert( $wpdb->prefix . 'icl_translations', $new );
  2991. $translation_id = $wpdb->insert_id;
  2992. $this->icl_translations_cache->clear();
  2993. }
  2994. } else { // it's a new element or we are removing it from a trid
  2995. if ( $translation_id = $wpdb->get_var( "
  2996. SELECT translation_id
  2997. FROM {$wpdb->prefix}icl_translations WHERE element_type='{$el_type}' AND element_id='{$el_id}' AND element_id IS NOT NULL" )
  2998. ) {
  2999. $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}icl_translations WHERE translation_id=%d", $translation_id ) );
  3000. $this->icl_translations_cache->clear();
  3001. }
  3002. $trid = 1 + $wpdb->get_var( "SELECT MAX(trid) FROM {$wpdb->prefix}icl_translations" );
  3003. $new = array(
  3004. 'trid' => $trid, 'element_type' => $el_type, 'language_code' => $language_code
  3005. );
  3006. if ( $el_id ) {
  3007. $new[ 'element_id' ] = $el_id;
  3008. }
  3009. $wpdb->insert( $wpdb->prefix . 'icl_translations', $new );
  3010. $translation_id = $wpdb->insert_id;
  3011. }
  3012. if ( $translation_id && substr( $el_type, 0, 4 ) === 'tax_' ) {
  3013. $taxonomy = substr( $el_type, 4 );
  3014. do_action( 'created_term_translation', $taxonomy, $el_id, $language_code );
  3015. }
  3016. return $translation_id;
  3017. }
  3018. function delete_element_translation( $trid, $el_type, $language_code = false )
  3019. {
  3020. global $wpdb;
  3021. $trid = intval( $trid );
  3022. $el_type = esc_sql( $el_type );
  3023. $where = '';
  3024. $delete_args = array($trid, $el_type);
  3025. if ( $language_code ) {
  3026. $where .= " AND language_code=%s";
  3027. $delete_args[] = $language_code;
  3028. }
  3029. $delete_sql = "DELETE FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND element_type=%s" . $where;
  3030. $delete_sql_prepared = $wpdb->prepare($delete_sql, $delete_args);
  3031. $wpdb->query( $delete_sql_prepared );
  3032. $this->icl_translations_cache->clear();
  3033. }
  3034. function get_element_language_details( $el_id, $el_type = 'post_post' )
  3035. {
  3036. $cache_key = $el_id . ':' . $el_type;
  3037. $cache_group = 'element_language_details';
  3038. $cached_details = wp_cache_get($cache_key, $cache_group);
  3039. if($cached_details) return $cached_details;
  3040. global $wpdb;
  3041. static $pre_load_done = false;
  3042. if ( !$pre_load_done && !ICL_DISABLE_CACHE ) {
  3043. // search previous queries for a group of posts
  3044. foreach ( $this->queries as $query ) {
  3045. $pos = strstr( $query, 'post_id IN (' );
  3046. if ( $pos !== false ) {
  3047. $group = substr( $pos, 10 );
  3048. $group = substr( $group, 0, strpos( $group, ')' ) + 1 );
  3049. $query = "SELECT element_id, trid, language_code, source_language_code
  3050. FROM {$wpdb->prefix}icl_translations
  3051. WHERE element_id IN {$group} AND element_type=%s";
  3052. $query_prepared = $wpdb->prepare($query, $el_type );
  3053. $ret = $wpdb->get_results( $query_prepared );
  3054. foreach ( $ret as $details ) {
  3055. if ( isset( $this->icl_translations_cache ) ) {
  3056. $this->icl_translations_cache->set( $details->element_id . $el_type, $details );
  3057. }
  3058. }
  3059. // get the taxonomy for the posts for later use
  3060. // categories first
  3061. $query = "SELECT DISTINCT(tr.term_taxonomy_id), tt.term_id, tt.taxonomy, icl.trid, icl.language_code, icl.source_language_code
  3062. FROM {$wpdb->prefix}term_relationships as tr
  3063. LEFT JOIN {$wpdb->prefix}term_taxonomy AS tt
  3064. ON tr.term_taxonomy_id = tt.term_taxonomy_id
  3065. LEFT JOIN {$wpdb->prefix}icl_translations as icl ON tr.term_taxonomy_id = icl.element_id
  3066. WHERE tr.object_id IN {$group}
  3067. AND (icl.element_type='tax_category' and tt.taxonomy='category')
  3068. ";
  3069. $query .= "UNION
  3070. ";
  3071. $query .= "SELECT DISTINCT(tr.term_taxonomy_id), tt.term_id, tt.taxonomy, icl.trid, icl.language_code, icl.source_language_code
  3072. FROM {$wpdb->prefix}term_relationships as tr
  3073. LEFT JOIN {$wpdb->prefix}term_taxonomy AS tt
  3074. ON tr.term_taxonomy_id = tt.term_taxonomy_id
  3075. LEFT JOIN {$wpdb->prefix}icl_translations as icl ON tr.term_taxonomy_id = icl.element_id
  3076. WHERE tr.object_id IN {$group}
  3077. AND (icl.element_type='tax_post_tag' and tt.taxonomy='post_tag')";
  3078. global $wp_taxonomies;
  3079. $custom_taxonomies = array_diff( array_keys( $wp_taxonomies ), array( 'post_tag', 'category', 'link_category' ) );
  3080. if ( !empty( $custom_taxonomies ) ) {
  3081. foreach ( $custom_taxonomies as $tax ) {
  3082. $query .= " UNION
  3083. SELECT DISTINCT(tr.term_taxonomy_id), tt.term_id, tt.taxonomy, icl.trid, icl.language_code, icl.source_language_code
  3084. FROM {$wpdb->prefix}term_relationships as tr
  3085. LEFT JOIN {$wpdb->prefix}term_taxonomy AS tt
  3086. ON tr.term_taxonomy_id = tt.term_taxonomy_id
  3087. LEFT JOIN {$wpdb->prefix}icl_translations as icl ON tr.term_taxonomy_id = icl.element_id
  3088. WHERE tr.object_id IN {$group}
  3089. AND (icl.element_type='tax_{$tax}' and tt.taxonomy='{$tax}')";
  3090. }
  3091. }
  3092. $ret = $wpdb->get_results( $query );
  3093. foreach ( $ret as $details ) {
  3094. // save language details
  3095. $lang_details = new stdClass();
  3096. $lang_details->trid = $details->trid;
  3097. $lang_details->language_code = $details->language_code;
  3098. $lang_details->source_language_code = $details->source_language_code;
  3099. if ( isset( $this->icl_translations_cache ) ) {
  3100. $this->icl_translations_cache->set( $details->term_taxonomy_id . 'tax_' . $details->taxonomy, $lang_details );
  3101. // save the term taxonomy
  3102. $this->icl_term_taxonomy_cache->set( 'category_' . $details->term_id, $details->term_taxonomy_id );
  3103. }
  3104. }
  3105. break;
  3106. }
  3107. }
  3108. $pre_load_done = true;
  3109. }
  3110. if ( isset( $this->icl_translations_cache ) && $this->icl_translations_cache->has_key( $el_id . $el_type ) ) {
  3111. return $this->icl_translations_cache->get( $el_id . $el_type );
  3112. }
  3113. $details_prepared_sql = $wpdb->prepare( "
  3114. SELECT trid, language_code, source_language_code
  3115. FROM {$wpdb->prefix}icl_translations
  3116. WHERE element_id=%d AND element_type=%s", array( $el_id, $el_type ) );
  3117. $details = $wpdb->get_row( $details_prepared_sql );
  3118. if ( isset( $this->icl_translations_cache ) ) {
  3119. $this->icl_translations_cache->set( $el_id . $el_type, $details );
  3120. }
  3121. wp_cache_add($cache_key, $details, $cache_group);
  3122. return $details;
  3123. }
  3124. //if set option "When deleting a taxonomy (category, tag or custom), delete translations as well"
  3125. //when editing post and deleting tag or category or custom taxonomy in original language then delete this taxonomy in other languages
  3126. function deleted_term_relationships( $object_id, $delete_terms )
  3127. {
  3128. global $wpdb;
  3129. if ( $this->settings[ 'sync_post_taxonomies' ] ) {
  3130. $post = get_post( $object_id );
  3131. $trid = $this->get_element_trid( $object_id, 'post_' . $post->post_type );
  3132. if ( $trid ) {
  3133. $translations = $this->get_element_translations( $trid, 'post_' . $post->post_type );
  3134. foreach ( $translations as $translation ) {
  3135. if ( $translation->original == 1 && $translation->element_id == $object_id ) {
  3136. $taxonomies = get_object_taxonomies( $post->post_type );
  3137. foreach ( $taxonomies as $taxonomy ) {
  3138. foreach ( $delete_terms as $delete_term ) {
  3139. $trid = $this->get_element_trid( $delete_term, 'tax_' . $taxonomy );
  3140. if ( $trid ) {
  3141. $tags = $this->get_element_translations( $trid, 'tax_' . $taxonomy );
  3142. foreach ( $tags as $tag ) {
  3143. if ( !$tag->original && isset( $translations[ $tag->language_code ] ) ) {
  3144. $translated_post = $translations[ $tag->language_code ];
  3145. $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id = $tag->element_id", $translated_post->element_id ) );
  3146. }
  3147. }
  3148. }
  3149. }
  3150. }
  3151. }
  3152. }
  3153. }
  3154. }
  3155. }
  3156. function save_post_actions( $pidd, $post )
  3157. {
  3158. global $wpdb;
  3159. wp_defer_term_counting( true );
  3160. list( $post_type, $post_status ) = $wpdb->get_row( "SELECT post_type, post_status FROM {$wpdb->posts} WHERE ID = " . $pidd, ARRAY_N );
  3161. // exceptions
  3162. if ( !$this->is_translated_post_type( $post_type ) || (isset( $post) && $post->post_status == "auto-draft" ) || isset( $_POST[ 'autosave' ] ) || isset( $_POST[ 'skip_sitepress_actions' ] ) || ( isset( $_POST[ 'post_ID' ] ) && $_POST[ 'post_ID' ] != $pidd ) || ( isset( $_POST[ 'post_type' ] ) && $_POST[ 'post_type' ] == 'revision' ) || $post_type == 'revision' || get_post_meta( $pidd, '_wp_trash_meta_status', true ) || ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'untrash' )) {
  3163. wp_defer_term_counting( false );
  3164. return;
  3165. }
  3166. $default_language = $this->get_default_language();
  3167. if(!isset($post) && $pidd) {
  3168. $post = get_post($pidd);
  3169. }
  3170. // exception for auto-drafts - setting the right language
  3171. // allow post arguments to be passed via wp_insert_post directly and not be expected on $_POST exclusively
  3172. $post_vars = (array)$_POST;
  3173. foreach ( (array)$post as $k => $v ) {
  3174. $post_vars[ $k ] = $v;
  3175. }
  3176. if ( !isset( $post_vars[ 'post_type' ] ) ) {
  3177. $post_vars[ 'post_type' ] = $post_type;
  3178. }
  3179. $element_type = 'post_' . $post_type;
  3180. $language_code = false;
  3181. if ( isset( $post_vars[ 'action' ] ) && $post_vars[ 'action' ] == 'post-quickpress-publish' ) {
  3182. $post_id = $pidd;
  3183. $language_code = $default_language;
  3184. } elseif ( isset( $_GET[ 'bulk_edit' ] ) ) {
  3185. $post_id = $pidd;
  3186. } else {
  3187. $post_id = isset( $post_vars[ 'post_ID' ] ) ? $post_vars[ 'post_ID' ] : $pidd; //latter case for XML-RPC publishing
  3188. if ( isset( $post_vars[ 'icl_post_language' ] ) ) {
  3189. $language_code = $post_vars[ 'icl_post_language' ];
  3190. } elseif ( isset( $_GET[ 'lang' ] ) ) {
  3191. $language_code = $_GET[ 'lang' ];
  3192. } elseif ( $_ldet = $this->get_element_language_details( $post_id, $element_type ) ) {
  3193. $language_code = $_ldet->language_code;
  3194. } elseif(isset($this->this_lang)) {
  3195. $language_code = $this->this_lang;
  3196. } else {
  3197. $language_code = $default_language; //latter case for XML-RPC publishing
  3198. }
  3199. }
  3200. if ( isset( $post_vars[ 'action' ] ) && $post_vars[ 'action' ] == 'inline-save' || isset( $_GET[ 'bulk_edit' ] ) || isset( $_GET[ 'doing_wp_cron' ] ) || ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'untrash' ) ) {
  3201. $res = $this->get_element_language_details($post_id, 'post_' . $post->post_type);
  3202. if(!isset($res) || !$res) return;
  3203. $language_code = $res->language_code;
  3204. $trid = $res->trid;
  3205. } else {
  3206. if ( isset( $post_vars[ 'icl_trid' ] ) ) {
  3207. $trid = @intval( $post_vars[ 'icl_trid' ] );
  3208. } elseif ( isset( $_GET[ 'trid' ] ) ) {
  3209. $trid = @intval( $_GET[ 'trid' ] );
  3210. } else {
  3211. $trid = $this->get_element_trid( $post_id, 'post_' . $post->post_type );
  3212. }
  3213. // see if we have a "translation of" setting.
  3214. if ( isset( $post_vars[ 'icl_translation_of' ] ) ) {
  3215. if ( is_numeric( $post_vars[ 'icl_translation_of' ] ) ) {
  3216. $translation_of_data_prepared = $wpdb->prepare( "SELECT trid, language_code FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", $post_vars[ 'icl_translation_of' ], 'post_' . $post->post_type );
  3217. list($trid, $source_language) = $wpdb->get_row( $translation_of_data_prepared, 'ARRAY_N' );
  3218. } else {
  3219. if ( empty( $post_vars[ 'icl_trid' ] ) ) {
  3220. $trid = null;
  3221. }
  3222. }
  3223. }
  3224. }
  3225. if ( isset( $_POST[ 'action' ] ) && $_POST[ 'action' ] == 'inline-save' ) {
  3226. $trid = $this->get_element_trid( $post_id, 'post_' . $post_type );
  3227. } else if ( isset( $post_vars[ 'icl_translation_of' ] ) && $post_vars[ 'icl_translation_of' ] == 'none' ) {
  3228. $trid = null;
  3229. }
  3230. if (!$trid) {
  3231. $trid_from_referrer = $this->get_trid_from_referer();
  3232. if ($trid_from_referrer) {
  3233. $trid = $trid_from_referrer;
  3234. }
  3235. }
  3236. if ( ! $this->is_active_language( $language_code ) ) {
  3237. $language_code = $default_language;
  3238. }
  3239. // set trid if front-end translation creating
  3240. $trid = apply_filters( 'wpml_save_post_trid_value', $trid, $post_status );
  3241. // set post language if front-end translation creating
  3242. $language_code = apply_filters( 'wpml_save_post_lang', $language_code );
  3243. // after getting the right trid set the source language from it by referring to the root translation
  3244. // of this trid, in case no proper source language is set already
  3245. if ( ! isset( $source_language ) || ! $source_language || $source_language == $language_code ) {
  3246. //if we are in the editor we can get the source language from the http-referer of the ajax request
  3247. $source_language = self::get_source_language_from_referer();
  3248. if ( ! $source_language ) {
  3249. //if getting the source language from the referer fails too, we get that of the first element of the trid
  3250. $source_language = self::get_source_language_by_trid( $trid );
  3251. }
  3252. }
  3253. /* Before setting the language of the post to be saved, check if a translation in this language already exists
  3254. * This check is necessary, so that synchronization actions like thrashing or un-trashing of posts, do not lead to
  3255. * database corruption, due to erroneously changing a posts language into a state,
  3256. * where it collides with an existing translation. While the UI prevents this sort of action for the most part,
  3257. * this is not necessarily the case for other plugins like TM.
  3258. * The logic here first of all checks if an existing translation id is present in the desired language_code.
  3259. * If so but this translation is actually not the currently to be saved post,
  3260. * then this post will be saved to its current language. If the translation already exists,
  3261. * the existing translation id will be used. In all other cases a new entry in icl_translations will be created.
  3262. */
  3263. $existing_translations = $this->get_element_translations( $trid, $element_type );
  3264. if ( $existing_translations && isset( $existing_translations[ $language_code ] ) ) {
  3265. $current_language_details = $this->get_element_language_details( $post_id, $element_type );
  3266. $existing_translation = $existing_translations[ $language_code ];
  3267. if ( $current_language_details
  3268. && isset( $current_language_details->language_code )
  3269. && $existing_translation
  3270. && isset( $existing_translation->element_id )
  3271. && isset( $current_language_details->element_id )
  3272. && $existing_translation->element_id != $current_language_details->element_id
  3273. ) {
  3274. $translation_id = $existing_translations[ $current_language_details->language_code ]->translation_id;
  3275. $language_code = $current_language_details->language_code;
  3276. } else {
  3277. $translation_id = $existing_translations[ $existing_translation->language_code ]->translation_id;
  3278. }
  3279. } else {
  3280. $translation_id = $this->set_element_language_details( $post_id, $element_type, $trid, $language_code, $source_language );
  3281. }
  3282. //get trid of $translation_id
  3283. $translated_id_trid = $wpdb->get_var( $wpdb->prepare( "SELECT trid FROM {$wpdb->prefix}icl_translations WHERE translation_id=%d", array( $translation_id) ) );
  3284. //get all translations
  3285. $translated_element_id = $wpdb->get_col( $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d", $translated_id_trid ) );
  3286. if ( !in_array( $post_type, array( 'post', 'page' ) ) && !$this->is_translated_post_type( $post_type ) ) {
  3287. wp_defer_term_counting( false );
  3288. return;
  3289. }
  3290. // synchronize the page order for translations
  3291. if ( $trid && $this->settings[ 'sync_page_ordering' ] && $translated_element_id && is_array( $translated_element_id ) ) {
  3292. $menu_order = esc_sql( $post_vars[ 'menu_order' ] );
  3293. // Only use non-null element ids for the menu ordering.
  3294. $non_null_eids = array_filter( $translated_element_id );
  3295. $wpdb->query( "UPDATE {$wpdb->posts} SET menu_order={$menu_order} WHERE ID IN (" . join( ',', $non_null_eids ) . ")" );
  3296. }
  3297. // synchronize the page parent for translations
  3298. if ( $trid && $this->settings[ 'sync_page_parent' ] ) {
  3299. $original_id = $this->get_original_element_id($post_id, 'post_' . $post_vars[ 'post_type' ]);
  3300. if ($original_id == $post_id) {
  3301. $translations = $this->get_element_translations( $trid, 'post_' . $post_vars[ 'post_type' ] );
  3302. foreach ( $translations as $target_lang => $target_details ) {
  3303. if ( $target_lang != $language_code ) {
  3304. if ( $target_details->element_id ) {
  3305. $this->fix_translated_parent( $post_id, $target_details->element_id, $target_lang);
  3306. }
  3307. }
  3308. }
  3309. }
  3310. }
  3311. // synchronize the page template
  3312. if ( isset( $post_vars[ 'page_template' ] ) && $trid && $post_vars[ 'post_type' ] == 'page' && $this->settings[ 'sync_page_template' ] ) {
  3313. if ( $translated_element_id && is_array($translated_element_id) ) {
  3314. foreach ( $translated_element_id as $tp ) {
  3315. if ( $tp != $post_id ) {
  3316. update_post_meta( $tp, '_wp_page_template', $post_vars[ 'page_template' ] );
  3317. }
  3318. }
  3319. }
  3320. }
  3321. // synchronize comment and ping status
  3322. if ( $trid && ( $this->settings[ 'sync_ping_status' ] || $this->settings[ 'sync_comment_status' ] ) ) {
  3323. $arr = array();
  3324. if ( $this->settings[ 'sync_comment_status' ] ) {
  3325. $arr[ 'comment_status' ] = $post_vars[ 'comment_status' ];
  3326. }
  3327. if ( $this->settings[ 'sync_ping_status' ] ) {
  3328. $arr[ 'ping_status' ] = $post_vars[ 'ping_status' ];
  3329. }
  3330. if ( !empty( $arr ) && $translated_element_id && is_array($translated_element_id) ) {
  3331. foreach ( $translated_element_id as $tp ) {
  3332. if ( $tp != $post_id ) {
  3333. $wpdb->update( $wpdb->posts, $arr, array( 'ID' => $tp ) );
  3334. }
  3335. }
  3336. }
  3337. }
  3338. // copy custom fields from original
  3339. $translations = $this->get_element_translations( $trid, 'post_' . $post_vars[ 'post_type' ] );
  3340. if ( !empty( $translations ) ) {
  3341. $original_post_id = false;
  3342. foreach ( $translations as $t ) {
  3343. if ( $t->original ) {
  3344. $original_post_id = $t->element_id;
  3345. break;
  3346. }
  3347. }
  3348. // this runs only for translated documents
  3349. if ( $post_id != $original_post_id ) {
  3350. $this->copy_custom_fields( $original_post_id, $post_id );
  3351. } else {
  3352. foreach ( $translations as $t ) {
  3353. if ( $original_post_id != $t->element_id ) {
  3354. $this->copy_custom_fields( $original_post_id, $t->element_id );
  3355. }
  3356. }
  3357. }
  3358. }
  3359. //sync posts stickiness
  3360. if ( isset( $post_vars[ 'post_type' ] ) && $post_vars[ 'post_type' ] == 'post' && isset( $post_vars[ 'action' ] ) && $post_vars[ 'action' ] != 'post-quickpress-publish' && $this->settings[ 'sync_sticky_flag' ] ) { //not for quick press
  3361. remove_filter( 'option_sticky_posts', array( $this, 'option_sticky_posts' ) ); // remove filter used to get language relevant stickies. get them all
  3362. $sticky_posts = get_option( 'sticky_posts' );
  3363. add_filter( 'option_sticky_posts', array( $this, 'option_sticky_posts' ) ); // add filter back
  3364. // get ids of the translations
  3365. if ( $trid ) {
  3366. $translations = $wpdb->get_col( $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d", $trid ) );
  3367. } else {
  3368. $translations = array();
  3369. }
  3370. if ( isset( $post_vars[ 'sticky' ] ) && $post_vars[ 'sticky' ] == 'sticky' ) {
  3371. $sticky_posts = array_unique( array_merge( $sticky_posts, $translations ) );
  3372. } else {
  3373. //makes sure translations are not set to sticky if this posts switched from sticky to not-sticky
  3374. $sticky_posts = array_diff( $sticky_posts, $translations );
  3375. }
  3376. update_option( 'sticky_posts', $sticky_posts );
  3377. }
  3378. //sync private flag
  3379. if ( $this->settings[ 'sync_private_flag' ] ) {
  3380. if ( $post_status == 'private' && ( empty( $post_vars[ 'original_post_status' ] ) || $post_vars[ 'original_post_status' ] != 'private' ) ) {
  3381. if ( $translated_element_id && is_array($translated_element_id) ) {
  3382. foreach ( $translated_element_id as $tp ) {
  3383. if ( $tp != $post_id ) {
  3384. $wpdb->update( $wpdb->posts, array( 'post_status' => 'private' ), array( 'ID' => $tp ) );
  3385. }
  3386. }
  3387. }
  3388. } elseif ( $post_status != 'private' && isset( $post_vars[ 'original_post_status' ] ) && $post_vars[ 'original_post_status' ] == 'private' ) {
  3389. if ( $translated_element_id && is_array($translated_element_id) ) {
  3390. foreach ( $translated_element_id as $tp ) {
  3391. if ( $tp != $post_id ) {
  3392. $wpdb->update( $wpdb->posts, array( 'post_status' => $post_status ), array( 'ID' => $tp ) );
  3393. }
  3394. }
  3395. }
  3396. }
  3397. }
  3398. //sync post format
  3399. if ( $this->settings[ 'sync_post_format' ] && function_exists( 'set_post_format' ) ) {
  3400. $format = get_post_format( $post_id );
  3401. if ( $translated_element_id && is_array($translated_element_id) ) {
  3402. foreach ( $translated_element_id as $tp ) {
  3403. if ( $tp != $post_id ) {
  3404. set_post_format( $tp, $format );
  3405. }
  3406. }
  3407. }
  3408. }
  3409. // sync post dates
  3410. if ( !empty( $this->settings[ 'sync_post_date' ] ) ) {
  3411. if ( $language_code == $default_language ) {
  3412. if ( $translated_element_id && is_array($translated_element_id) ) {
  3413. $post_date = $wpdb->get_var( $wpdb->prepare( "SELECT post_date FROM {$wpdb->posts} WHERE ID=%d", $post_id ) );
  3414. foreach ( $translated_element_id as $tp ) {
  3415. if ( $tp != $post_id ) {
  3416. $wpdb->update( $wpdb->posts, array( 'post_date' => $post_date, 'post_date_gmt' => get_gmt_from_date( $post_date ) ), array( 'ID' => $tp ) );
  3417. }
  3418. }
  3419. }
  3420. } else {
  3421. if ( !is_null( $trid ) ) {
  3422. $source_lang = isset( $_GET[ 'source_lang' ] ) ? $_GET[ 'source_lang' ] : $default_language;
  3423. $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 ) );
  3424. if ( ! $original_id ) {
  3425. global $post;
  3426. if ( isset ( $post->ID ) ) {
  3427. $original_id = $post->ID;
  3428. }
  3429. }
  3430. if ( isset ( $original_id ) ) {
  3431. $post_date = $wpdb->get_var( $wpdb->prepare( "SELECT post_date FROM {$wpdb->posts} WHERE ID=%d", $original_id ) );
  3432. $wpdb->update( $wpdb->posts, array( 'post_date' => $post_date, 'post_date_gmt' => get_gmt_from_date( $post_date ) ), array( 'ID' => $post_id ) );
  3433. }
  3434. }
  3435. }
  3436. }
  3437. if ( isset( $post_vars[ 'icl_tn_note' ] ) ) {
  3438. update_post_meta( $post_id, '_icl_translator_note', $post_vars[ 'icl_tn_note' ] );
  3439. }
  3440. //fix guid
  3441. if ( $this->settings[ 'language_negotiation_type' ] == 2 && $this->get_current_language() != $default_language ) {
  3442. $guid = $this->convert_url( get_post_field( 'guid', $post_id ) );
  3443. $wpdb->update( $wpdb->posts, array( 'guid' => $guid ), array( 'id' => $post_id ) );
  3444. }
  3445. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  3446. icl_cache_clear( $post_vars[ 'post_type' ] . 's_per_language', true );
  3447. wp_defer_term_counting( false );
  3448. }
  3449. function get_trid_from_referer() {
  3450. if (isset($_SERVER['HTTP_REFERER'])) {
  3451. $query = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY);
  3452. parse_str($query);
  3453. if (isset($trid)) {
  3454. return $trid;
  3455. }
  3456. }
  3457. return false;
  3458. }
  3459. static function get_source_language_from_referer() {
  3460. if ( isset( $_SERVER[ 'HTTP_REFERER' ] ) ) {
  3461. $query = parse_url( $_SERVER[ 'HTTP_REFERER' ], PHP_URL_QUERY );
  3462. parse_str( $query );
  3463. if ( isset( $source_lang ) ) {
  3464. return $source_lang;
  3465. }
  3466. }
  3467. return false;
  3468. }
  3469. /**
  3470. * If post has translations and is the original, returns false
  3471. *
  3472. * @param $post WP_Post
  3473. *
  3474. * @return bool
  3475. */
  3476. function can_post_be_deleted( $post )
  3477. {
  3478. global $sitepress;
  3479. $sitepress_settings = $sitepress->get_settings();
  3480. if ( $sitepress_settings[ 'sync_delete' ] != 1 ) {
  3481. $trid = $sitepress->get_element_trid( $post->ID, 'post_' . $post->post_type );
  3482. if ( $trid ) {
  3483. $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
  3484. $original_id = false;
  3485. $can_delete = true;
  3486. foreach ( $translations as $translation ) {
  3487. //TODO: check that the post exists too
  3488. if ( $translation->language_code != $sitepress->get_default_language() ) {
  3489. $can_delete = false;
  3490. } else {
  3491. $original_id = $translation->element_id;
  3492. }
  3493. }
  3494. if ( $post->ID == $original_id && !$can_delete ) {
  3495. return false;
  3496. } else {
  3497. return true;
  3498. }
  3499. }
  3500. }
  3501. return true;
  3502. }
  3503. function wp_unique_post_slug( $slug, $post_id, $post_status, $post_type, $post_parent ) {
  3504. global $wpdb;
  3505. $cache_key_array = array( $slug, $post_id, $post_status, $post_type, $post_parent );
  3506. $cache_key = md5( serialize( $cache_key_array ) );
  3507. $cache_group = 'wp_unique_post_slug';
  3508. $cache_found = false;
  3509. $result = wp_cache_get( $cache_key, $cache_group, false, $cache_found );
  3510. if ( $cache_found ) {
  3511. return $result;
  3512. }
  3513. if ( $this->is_translated_post_type( $post_type ) && $post_id ) {
  3514. $post_prepared = $wpdb->prepare( "SELECT ID, post_status, post_name, post_title FROM {$wpdb->posts} WHERE ID=%d", $post_id );
  3515. $post = $wpdb->get_row( $post_prepared );
  3516. if ( !in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) {
  3517. global $wp_rewrite;
  3518. $feeds = $wp_rewrite->feeds;
  3519. if ( !is_array( $feeds ) ) {
  3520. $feeds = array();
  3521. }
  3522. $post_language = $this->get_language_for_element( $post_id, 'post_' . $post_type );
  3523. if ( isset( $_POST[ 'new_slug' ] ) ) {
  3524. if ( $_POST[ 'new_slug' ] === '' ) {
  3525. $slug = sanitize_title( $_POST[ 'new_title' ], $post->ID );
  3526. } else {
  3527. $slug = sanitize_title( $_POST[ 'new_slug' ], $post->ID );
  3528. }
  3529. } elseif ( isset( $_POST[ 'action' ] ) && $_POST[ 'action' ] == 'inline-save' ) {
  3530. $slug = sanitize_title( $_POST[ 'post_name' ], $post->ID );
  3531. } else {
  3532. $slug = sanitize_title( $post->post_name ? $post->post_name : $post->post_title, $post->ID );
  3533. }
  3534. $hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
  3535. if ( in_array( $post_type, $hierarchical_post_types ) ) {
  3536. // Page slugs must be unique within their own trees. Pages are in a separate
  3537. // namespace than posts so page slugs are allowed to overlap post slugs.
  3538. $post_name_check_sql = "SELECT p.post_name
  3539. FROM $wpdb->posts p
  3540. JOIN {$wpdb->prefix}icl_translations t ON p.ID = t.element_id AND t.element_type = %s
  3541. WHERE p.post_name = %s AND p.post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' )
  3542. AND p.ID != %d AND p.post_parent = %d AND t.language_code = %s LIMIT 1";
  3543. $post_name_check = $wpdb->get_var( $wpdb->prepare( $post_name_check_sql, 'post_' . $post_type, $slug, $post_id, $post_parent, $post_language ) );
  3544. 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 ) ) {
  3545. $suffix = 2;
  3546. do {
  3547. $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  3548. $post_name_check = $wpdb->get_var( $wpdb->prepare( $post_name_check_sql, 'post_' . $post_type, $alt_post_name, $post_id, $post_parent, $post_language ) );
  3549. $suffix++;
  3550. } while ( $post_name_check );
  3551. $slug = $alt_post_name;
  3552. }
  3553. } else {
  3554. // Post slugs must be unique across all posts.
  3555. $post_name_check_sql = "SELECT p.post_name
  3556. FROM $wpdb->posts p
  3557. JOIN {$wpdb->prefix}icl_translations t ON p.ID = t.element_id AND t.element_type = %s
  3558. WHERE p.post_name = %s AND p.post_type = %s AND p.ID != %d AND t.language_code = %s LIMIT 1";
  3559. $post_name_check_prepared = $wpdb->prepare( $post_name_check_sql, 'post_' . $post_type, $slug, $post_type, $post_id, $post_language );
  3560. $post_name_check = $wpdb->get_var( $post_name_check_prepared );
  3561. if ( $post_name_check || in_array( $slug, $feeds ) || apply_filters( 'wp_unique_post_slug_is_bad_flat_slug', false, $slug, $post_type ) ) {
  3562. $suffix = 2;
  3563. do {
  3564. $alt_post_name = substr( $slug, 0, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
  3565. $post_name_check = $wpdb->get_var( $wpdb->prepare( $post_name_check_sql, 'post_' . $post_type, $alt_post_name, $post_type, $post_id, $post_language ) );
  3566. $suffix++;
  3567. } while ( $post_name_check );
  3568. $slug = $alt_post_name;
  3569. }
  3570. }
  3571. if ( isset( $_POST[ 'new_slug' ] ) ) {
  3572. $wpdb->update( $wpdb->posts, array( 'post_name' => $slug ), array( 'ID' => $post_id ) );
  3573. }
  3574. }
  3575. }
  3576. wp_cache_set( $cache_key, $slug, $cache_group );
  3577. return $slug;
  3578. }
  3579. /** Fix parent of translation
  3580. * User changed parent for $orginal_id and we are setting proper parent for $translation_id in $language_code_translated language
  3581. * @param $original_id - id of post with changed parent
  3582. * @param $translated_id - translation of changed post
  3583. * @param $translation_language - language we are fixing
  3584. */
  3585. function fix_translated_parent( $original_id, $translated_id, $translation_language )
  3586. {
  3587. global $wpdb;
  3588. $icl_post_type = isset( $_POST[ 'post_type' ] ) ? 'post_' . $_POST[ 'post_type' ] : 'post_page';
  3589. // get parent of original page
  3590. $original_parent = $wpdb->get_var( $wpdb->prepare( "SELECT post_parent FROM {$wpdb->posts} WHERE ID = %d AND post_type = %s", array($original_id, 'page') ) );
  3591. if ( !is_null( $original_parent ) ) {
  3592. if ( $original_parent == 0){
  3593. $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_parent=%d WHERE ID = %d", array( 0, $translated_id ) ) );
  3594. }else {
  3595. $trid = $this->get_element_trid( $original_parent, $icl_post_type );
  3596. if ( $trid ) {
  3597. //get parent translations
  3598. $translations_of_parent = $this->get_element_translations( $trid, $icl_post_type );
  3599. if ( isset( $translations_of_parent[ $translation_language ] ) ) {
  3600. $current_translated_parent = $wpdb->get_var( $wpdb->prepare( "SELECT post_parent FROM {$wpdb->posts} WHERE ID = %d", array($translated_id) ) );
  3601. if ( !is_null( $translations_of_parent[ $translation_language ]->element_id ) && $current_translated_parent != $translations_of_parent[ $translation_language ]->element_id ) {
  3602. $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_parent=%d WHERE ID = %d", array( $translations_of_parent[$translation_language]->element_id, $translated_id ) ) );
  3603. }
  3604. }
  3605. }
  3606. }
  3607. }
  3608. }
  3609. /* Custom fields synchronization - START */
  3610. function _sync_custom_field( $post_id_from, $post_id_to, $meta_key )
  3611. {
  3612. global $wpdb;
  3613. $values_from_prepared = $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id=%d AND meta_key=%s", array($post_id_from, $meta_key) );
  3614. $values_to_prepared = $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE post_id=%d AND meta_key=%s", array($post_id_to, $meta_key) );
  3615. $values_from = $wpdb->get_col( $values_from_prepared );
  3616. $values_to = $wpdb->get_col( $values_to_prepared );
  3617. // handle the case of 1 key - 1 value with updates in case of change
  3618. // if ( count( $values_from ) == 1 && count( $values_to ) == 1 ) {
  3619. //
  3620. // if ( $values_from[ 0 ] != $values_to[ 0 ] ) {
  3621. // $update_prepared = $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value=%s WHERE post_id=%d AND meta_key=%s", array( $values_from[ 0 ], $post_id_to, $meta_key ) );
  3622. // $wpdb->query( $update_prepared );
  3623. // }
  3624. //
  3625. // } else {
  3626. //removed
  3627. $removed = array_diff( $values_to, $values_from );
  3628. foreach ( $removed as $v ) {
  3629. $delete_prepared = $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE post_id=%d AND meta_key=%s AND meta_value=%s", $post_id_to, $meta_key, $v );
  3630. $wpdb->query( $delete_prepared );
  3631. }
  3632. //added
  3633. $added = array_diff( $values_from, $values_to );
  3634. foreach ( $added as $v ) {
  3635. $insert_prepared = $wpdb->prepare( "INSERT INTO {$wpdb->postmeta}(post_id, meta_key, meta_value) VALUES(%d, %s, %s)", $post_id_to, $meta_key, $v );
  3636. $wpdb->query( $insert_prepared );
  3637. }
  3638. // }
  3639. }
  3640. function copy_custom_fields( $post_id_from, $post_id_to )
  3641. {
  3642. $cf_copy = array();
  3643. if ( isset( $this->settings[ 'translation-management' ][ 'custom_fields_translation' ] ) ) {
  3644. foreach ( $this->settings[ 'translation-management' ][ 'custom_fields_translation' ] as $meta_key => $option ) {
  3645. if ( $option == 1 ) {
  3646. $cf_copy[ ] = $meta_key;
  3647. }
  3648. }
  3649. }
  3650. foreach ( $cf_copy as $meta_key ) {
  3651. $meta_from = get_post_meta($post_id_from, $meta_key) ;
  3652. $meta_to = get_post_meta($post_id_to, $meta_key) ;
  3653. if($meta_from || $meta_to) {
  3654. $this->_sync_custom_field( $post_id_from, $post_id_to, $meta_key );
  3655. }
  3656. }
  3657. }
  3658. function update_post_meta( $meta_id, $object_id, $meta_key, $_meta_value )
  3659. {
  3660. return;
  3661. global $wpdb, $iclTranslationManagement;
  3662. // only handle custom fields that need to be copied
  3663. $custom_fields_translation = isset($this->settings[ 'translation-management' ][ 'custom_fields_translation' ]) ? $this->settings[ 'translation-management' ][ 'custom_fields_translation' ] : false;
  3664. if (!$custom_fields_translation || !isset( $custom_fields_translation[ $meta_key ] ) || !in_array( $custom_fields_translation[ $meta_key ], array( 1, 2 ) ) ) {
  3665. return;
  3666. }
  3667. $post = get_post( $object_id );
  3668. if ( $custom_fields_translation[ $meta_key ] == '2' ) {
  3669. $trid = $this->get_element_trid( $object_id, 'post_' . $post->post_type );
  3670. if ( $trid ) {
  3671. $translations = $this->get_element_translations( $trid, 'post_' . $post->post_type );
  3672. foreach ( $translations as $translation ) {
  3673. if ( $translation->original == 1 && $translation->element_id == $object_id ) {
  3674. $is_original = true;
  3675. break;
  3676. }
  3677. }
  3678. if ( isset( $is_original ) ) {
  3679. $md5 = $iclTranslationManagement->post_md5( $object_id );
  3680. foreach ( $translations as $translation ) {
  3681. if ( !$translation->original ) {
  3682. $emd5 = $wpdb->get_var( $wpdb->prepare( "SELECT md5 FROM {$wpdb->prefix}icl_translation_status WHERE translation_id = %d", $translation->translation_id ) );
  3683. if ( $md5 != $emd5 ) {
  3684. $translation_package = $iclTranslationManagement->create_translation_package( $object_id );
  3685. $translation_data = array(
  3686. 'translation_id' => $translation->translation_id,
  3687. 'needs_update' => 1,
  3688. 'md5' => $md5,
  3689. 'translation_package' => serialize( $translation_package )
  3690. );
  3691. list( $rid ) = $iclTranslationManagement->update_translation_status( $translation_data );
  3692. $translator_id_prepared = $wpdb->prepare( "SELECT translator_id FROM {$wpdb->prefix}icl_translation_status WHERE translation_id = %d", $translation->translation_id );
  3693. $translator_id = $wpdb->get_var( $translator_id_prepared );
  3694. $iclTranslationManagement->add_translation_job( $rid, $translator_id, $translation_package );
  3695. }
  3696. }
  3697. }
  3698. }
  3699. }
  3700. } else {
  3701. $translated_docs = $this->get_translatable_documents();
  3702. if ( !empty( $translated_docs[ $post->post_type ] ) ) {
  3703. $original_id = $this->get_original_element_id($object_id, 'post_' . $post->post_type, true, $all_statuses = true);
  3704. $trid = $this->get_element_trid( $object_id, 'post_' . $post->post_type );
  3705. if ( $trid ) {
  3706. $translations = $this->get_element_translations( $trid, 'post_' . $post->post_type, true, true );
  3707. // CASE of updating the original document (source)
  3708. if ( isset( $original_id ) ) {
  3709. if ( $object_id == $original_id ) {
  3710. foreach ( $translations as $t ) {
  3711. if ( $object_id != $t->element_id ) {
  3712. $this->_sync_custom_field( $object_id, $t->element_id, $meta_key, true );
  3713. }
  3714. }
  3715. } else { // CASE of updating the translated document (target) - don't let writing something else here
  3716. $_meta_value = get_post_meta($original_id, $meta_key);
  3717. $this->update_post_meta( $meta_id, $original_id, $meta_key, $_meta_value );
  3718. }
  3719. }
  3720. }
  3721. }
  3722. }
  3723. }
  3724. function delete_post_meta( $meta_id )
  3725. {
  3726. return;
  3727. if(!isset($this->settings[ 'translation-management' ][ 'custom_fields_translation' ])) return;
  3728. if ( !function_exists( 'get_post_meta_by_id' ) ) {
  3729. require_once ABSPATH . 'wp-admin/includes/post.php';
  3730. }
  3731. if ( is_array( $meta_id ) ) {
  3732. $meta_id = $meta_id[ 0 ];
  3733. }
  3734. $meta = get_post_meta_by_id( $meta_id );
  3735. if(!isset($this->settings[ 'translation-management' ][ 'custom_fields_translation' ][ $meta->meta_key ])) return;
  3736. $custom_fields_translation_meta = $this->settings[ 'translation-management' ][ 'custom_fields_translation' ][ $meta->meta_key ];
  3737. if ( $meta && in_array( $custom_fields_translation_meta, array( 1, 2 ) ) ) {
  3738. $post = get_post( $meta->post_id );
  3739. $translated_docs = $this->get_translatable_documents();
  3740. if ( !empty( $translated_docs[ $post->post_type ] ) ) {
  3741. $trid = $this->get_element_trid( $meta->post_id, 'post_' . $post->post_type );
  3742. if ( $trid ) {
  3743. $translations = $this->get_element_translations( $trid, 'post_' . $post->post_type );
  3744. if ( $translations ) {
  3745. foreach ( $translations as $t ) {
  3746. if ( $t->original ) {
  3747. $original_id = $t->element_id;
  3748. }
  3749. }
  3750. }
  3751. if ( isset( $original_id ) ) {
  3752. if ( $original_id == $meta->post_id ) {
  3753. foreach ( $translations as $t ) {
  3754. if ( !$t->original ) {
  3755. $this->_sync_custom_field( $meta->post_id, $t->element_id, $meta->meta_key, $custom_fields_translation_meta==1 );
  3756. }
  3757. }
  3758. } else {
  3759. $this->_sync_custom_field( $original_id, $meta->post_id, $meta->meta_key, $custom_fields_translation_meta==1 );
  3760. }
  3761. }
  3762. }
  3763. }
  3764. }
  3765. }
  3766. /* Custom fields synchronization - END */
  3767. function before_delete_post_actions( $post_id )
  3768. {
  3769. global $wpdb;
  3770. if ( !isset( $post_id ) || !$post_id ) {
  3771. $post = get_post();
  3772. $post_id = $post->ID;
  3773. } else {
  3774. $post = get_post( $post_id );
  3775. }
  3776. if ( $post == null ) {
  3777. return;
  3778. }
  3779. $post_type = $post->post_type;
  3780. //we need to save information which for which children we have to update translations after parent post delete
  3781. if ( is_post_type_hierarchical( $post_type ) && $this->settings[ 'sync_page_parent' ] && !$this->settings[ 'sync_delete' ] ) {
  3782. //get children of deleted post
  3783. $children_ids = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_parent=%d AND post_type=%s", array($post_id, $post_type) ) );
  3784. //cache value will be used in in deleted_post_actions
  3785. wp_cache_set('children_before_delete_post_actions_'.$post_id, $children_ids, 'icl_before_delete_post_actions');
  3786. }
  3787. }
  3788. function deleted_post_actions( $post_id )
  3789. {
  3790. global $wpdb;
  3791. if ( !isset( $post_id ) || !$post_id ) {
  3792. $post = get_post();
  3793. $post_id = $post->ID;
  3794. } else {
  3795. $post = get_post( $post_id );
  3796. }
  3797. if ( $post == null ) {
  3798. return;
  3799. }
  3800. $post_type = $post->post_type;
  3801. $post_type_exceptions = array('nav_menu_item');
  3802. if(in_array($post_type, $post_type_exceptions)) return;
  3803. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  3804. icl_cache_clear( $post_type . 's_per_language', true );
  3805. $element_type = 'post_' . $post_type;
  3806. $trid = $this->get_element_trid( $post_id, $element_type );
  3807. if ( $trid ) {
  3808. $language_details = $this->get_element_language_details( $post_id, $element_type );
  3809. if ( $language_details ) {
  3810. $is_original = ! $language_details->source_language_code;
  3811. $original_language = $language_details->language_code;
  3812. //delete translation for original language (icl_translations)
  3813. $this->delete_element_translation( $trid, $element_type, $language_details->language_code );
  3814. //select translations for all other languages (icl_translations)
  3815. $post_translations = $this->get_element_translations( $trid, $element_type, false, false, true );
  3816. if ( $post_translations ) {
  3817. //delete empty translations (icl_translations)
  3818. foreach ( $post_translations as $post_language => $post_translation ) {
  3819. if ( empty ( $post_translation->element_id ) ){
  3820. //delete element translation for given laguage
  3821. $this->delete_element_translation( $trid, $element_type, $post_language );
  3822. //remove translation from the list
  3823. unset( $post_translations[ $post_language ] );
  3824. }
  3825. }
  3826. }
  3827. //If we've just deleted the original and there are still translations, let's set the original to the first available translation
  3828. if ( $is_original && $post_translations ) {
  3829. $languages = $this->get_active_languages( true );
  3830. $languages = $this->order_languages( $languages );
  3831. $fallback_language = false;
  3832. $new_source_translation_id = false;
  3833. //Get first available languages (to keep their order)
  3834. foreach ( $languages as $language ) {
  3835. if ( $language[ 'code' ] != $original_language ) {
  3836. if ( isset( $post_translations[ $language[ 'code' ] ] ) ) {
  3837. $fallback_language = $language[ 'code' ];
  3838. $new_source_translation_id = $post_translations[ $fallback_language ]->element_id;
  3839. break;
  3840. }
  3841. }
  3842. }
  3843. foreach ( $post_translations as $post_translation ) {
  3844. $element_language_details = $this->get_element_language_details( $post_translation->element_id, $element_type );
  3845. if ( $post_translation->element_id == $new_source_translation_id ) {
  3846. $source_language = false;
  3847. } elseif ( $original_language == $element_language_details->source_language_code ) {
  3848. $source_language = $fallback_language;
  3849. } else {
  3850. $source_language = $element_language_details->source_language_code;
  3851. }
  3852. $update_data = array(
  3853. 'language_code' => $element_language_details->language_code
  3854. );
  3855. if ( $source_language ) {
  3856. $update_data[ 'source_language_code' ] = $source_language;
  3857. } else {
  3858. $update_data[ 'source_language_code' ] = null;
  3859. }
  3860. $update_where = array(
  3861. 'translation_id' => $post_translation->translation_id
  3862. );
  3863. $wpdb->update( $wpdb->prefix . 'icl_translations', $update_data, $update_where );
  3864. $_icl_lang_duplicate_of = get_post_meta( $post_translation->element_id, '_icl_lang_duplicate_of', true );
  3865. if ( $_icl_lang_duplicate_of ) {
  3866. if ( $element_language_details->language_code == $fallback_language ) {
  3867. delete_post_meta( $post_translation->element_id, '_icl_lang_duplicate_of' );
  3868. } else {
  3869. update_post_meta( $post_translation->element_id, '_icl_lang_duplicate_of', $new_source_translation_id );
  3870. }
  3871. }
  3872. }
  3873. }
  3874. }
  3875. // synchronize the page parent for translations only when we do not delete translations and only for hierarchical types
  3876. if ( is_post_type_hierarchical( $post_type ) && $this->settings[ 'sync_page_parent' ] && !$this->settings[ 'sync_delete' ] ) {
  3877. //get deleted post parent
  3878. $parent_trid = $this->get_element_trid( $post->post_parent, $element_type );
  3879. //get translations of deleted post parent
  3880. $parent_translations = $this->get_element_translations( $parent_trid, $element_type );
  3881. // get children of deleted post (stored in before_post_delete_actions)
  3882. $children_ids = wp_cache_get( 'children_before_delete_post_actions_' . $post_id, 'icl_before_delete_post_actions' );
  3883. if ( $children_ids ) {
  3884. //for each children of deleted post
  3885. foreach ( $children_ids as $child_id ) {
  3886. //get translations
  3887. $child_trid = $this->get_element_trid( $child_id, $element_type );
  3888. $child_translations = $this->get_element_translations( $child_trid, $element_type );
  3889. //for each translation of child
  3890. foreach ( $child_translations as $child_target_lang => $child_target_details ) {
  3891. //if parent translation exists and it is a translations (not child of deleted post)
  3892. if ( $child_target_details->element_id != $child_id ) {
  3893. if ( isset( $parent_translations[ $child_target_lang ]->element_id ) ) {
  3894. //set parent
  3895. $wpdb->update( $wpdb->posts, array( 'post_parent' => $parent_translations[ $child_target_lang ]->element_id ), array( 'ID' => $child_target_details->element_id ) );
  3896. } else {
  3897. $wpdb->update( $wpdb->posts, array( 'post_parent' => 0 ), array( 'ID' => $child_target_details->element_id ) );
  3898. }
  3899. }
  3900. }
  3901. }
  3902. }
  3903. // remove children of deleted post (stored in before_post_delete_actions)
  3904. wp_cache_delete( 'children_before_delete_post_actions_' . $post_id, 'icl_before_delete_post_actions' );
  3905. }
  3906. }
  3907. if ( !$this->settings[ 'sync_delete' ] ) {
  3908. return;
  3909. }
  3910. static $deleted_posts;
  3911. if ( isset( $deleted_posts[ $post_id ] ) ) {
  3912. return; // avoid infinite loop
  3913. }
  3914. if ( !isset( $_REQUEST['delete_all'] ) && !isset( $_REQUEST['delete_all2'] ) ) {
  3915. if ( ( empty( $deleted_posts ) || ( is_array( $deleted_posts ) && !isset( $deleted_posts[ $post_id ] ) ) ) ) {
  3916. $translations = $this->get_element_translations( $trid, $element_type );
  3917. foreach ( $translations as $t ) {
  3918. if ( $t->element_id != $post_id ) {
  3919. $deleted_posts[ ] = $post_id;
  3920. $post_exists_sql = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE id = %d", $t->element_id );
  3921. $post_exists = $wpdb->get_col( $post_exists_sql );
  3922. if ( $post_exists ) {
  3923. wp_delete_post( $t->element_id );
  3924. }
  3925. }
  3926. }
  3927. }
  3928. }
  3929. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  3930. icl_cache_clear( $post_type . 's_per_language', true );
  3931. }
  3932. function trash_post_actions( $post_id )
  3933. {
  3934. global $wpdb;
  3935. $post_type = $wpdb->get_var( "SELECT post_type FROM {$wpdb->posts} WHERE ID={$post_id}" );
  3936. // bulk deleting
  3937. // using this to not try to delete a post that's going to be deleted anyway
  3938. static $posts_to_delete_in_bulk;
  3939. if ( is_null( $posts_to_delete_in_bulk ) ) {
  3940. $posts_to_delete_in_bulk = isset( $_GET[ 'post' ] ) && is_array( $_GET[ 'post' ] ) ? $_GET[ 'post' ] : array();
  3941. }
  3942. if ( $this->settings[ 'sync_delete' ] ) {
  3943. static $trashed_posts = array();
  3944. if ( isset( $trashed_posts[ $post_id ] ) ) {
  3945. return; // avoid infinite loop
  3946. }
  3947. $trashed_posts[ $post_id ] = $post_id;
  3948. $trid = $this->get_element_trid( $post_id, 'post_' . $post_type );
  3949. $translations = $this->get_element_translations( $trid, 'post_' . $post_type );
  3950. foreach ( $translations as $t ) {
  3951. if ( $t->element_id != $post_id && !in_array( $t->element_id, $posts_to_delete_in_bulk ) ) {
  3952. wp_trash_post( $t->element_id );
  3953. }
  3954. }
  3955. }
  3956. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  3957. icl_cache_clear( $post_type . 's_per_language', true );
  3958. }
  3959. function untrashed_post_actions( $post_id )
  3960. {
  3961. global $wpdb;
  3962. $post_type = $wpdb->get_var( "SELECT post_type FROM {$wpdb->posts} WHERE ID={$post_id}" );
  3963. if ( $this->settings[ 'sync_delete' ] ) {
  3964. $trid = $this->get_element_trid( $post_id, 'post_' . $post_type );
  3965. $translations = $this->get_element_translations( $trid, 'post_' . $post_type );
  3966. foreach ( $translations as $t ) {
  3967. /* The first line of these checks ensures, that we are actually restoring a trashed post.
  3968. * The second line ensures, that this post is not going to be restored anyways through a bulk
  3969. * action from the UI.
  3970. */
  3971. if ( isset( $t->element_id ) && $t->element_id != $post_id && get_post_status( $t->element_id ) == 'trash'
  3972. && ! ( isset( $_REQUEST[ 'post' ] ) && is_array( $_REQUEST[ 'post' ] ) && in_array( $t->element_id, $_REQUEST[ 'post' ] ) )
  3973. ) {
  3974. remove_action( 'untrashed_post', array( $this, 'untrashed_post_actions' ) );
  3975. wp_untrash_post( $t->element_id );
  3976. add_action( 'untrashed_post', array( $this, 'untrashed_post_actions' ) );
  3977. }
  3978. }
  3979. }
  3980. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  3981. icl_cache_clear( $post_type . 's_per_language', true );
  3982. }
  3983. /**
  3984. * @param int $trid
  3985. * @param string $el_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category, post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment')
  3986. * @param bool $skip_empty
  3987. * @param bool $all_statuses
  3988. * @param bool $skip_cache
  3989. *
  3990. * @return array|bool|mixed
  3991. */
  3992. function get_element_translations( $trid, $el_type = 'post_post', $skip_empty = false, $all_statuses = false, $skip_cache = false )
  3993. {
  3994. $cache_key_args = array_filter( array( $trid, $el_type, $skip_empty, $all_statuses ) );
  3995. $cache_key = md5(json_encode( $cache_key_args ));
  3996. $cache_group = 'element_translations';
  3997. $temp_elements = $skip_cache ? false : wp_cache_get($cache_key, $cache_group);
  3998. if($temp_elements) return $temp_elements;
  3999. global $wpdb;
  4000. $translations = array();
  4001. $sel_add = '';
  4002. $where_add = '';
  4003. if ( $trid ) {
  4004. if ( 0 === strpos( $el_type, 'post_' ) ) {
  4005. $sel_add = ', p.post_title, p.post_status';
  4006. $join_add = " LEFT JOIN {$wpdb->posts} p ON t.element_id=p.ID";
  4007. $groupby_add = "";
  4008. if ( ! is_admin() && empty( $all_statuses ) && $el_type != 'post_attachment' ) {
  4009. // the current user may not be the admin but may have read private post/page caps!
  4010. if ( current_user_can( 'read_private_pages' ) || current_user_can( 'read_private_posts' ) ) {
  4011. $where_add .= " AND (p.post_status = 'publish' OR p.post_status = 'private' OR p.post_status = 'pending')";
  4012. } else {
  4013. $where_add .= " AND (";
  4014. $where_add .= "p.post_status = 'publish' OR p.post_status = 'pending' ";
  4015. if ( $uid = $this->get_current_user()->ID ) {
  4016. $where_add .= " OR (post_status in ('draft', 'private', 'pending') AND post_author = {$uid})";
  4017. }
  4018. $where_add .= ") ";
  4019. }
  4020. }
  4021. } elseif ( preg_match( '#^tax_(.+)$#', $el_type ) ) {
  4022. $sel_add = ', tm.name, tm.term_id, COUNT(tr.object_id) AS instances';
  4023. $join_add = " LEFT JOIN {$wpdb->term_taxonomy} tt ON t.element_id=tt.term_taxonomy_id
  4024. LEFT JOIN {$wpdb->terms} tm ON tt.term_id = tm.term_id
  4025. LEFT JOIN {$wpdb->term_relationships} tr ON tr.term_taxonomy_id=tt.term_taxonomy_id
  4026. ";
  4027. $groupby_add = "GROUP BY tm.term_id";
  4028. }
  4029. $where_add .= " AND t.trid='{$trid}'";
  4030. if ( !isset( $join_add ) ) {
  4031. $join_add = "";
  4032. }
  4033. if ( !isset( $groupby_add ) ) {
  4034. $groupby_add = "";
  4035. }
  4036. $query = "
  4037. SELECT t.translation_id, t.language_code, t.element_id, t.source_language_code, NULLIF(t.source_language_code, '') IS NULL AS original {$sel_add}
  4038. FROM {$wpdb->prefix}icl_translations t
  4039. {$join_add}
  4040. WHERE 1 {$where_add}
  4041. {$groupby_add}
  4042. ";
  4043. $ret = $wpdb->get_results( $query );
  4044. foreach ( $ret as $t ) {
  4045. if ( ( preg_match( '#^tax_(.+)$#', $el_type ) ) && $t->instances == 0 && !_icl_tax_has_objects_recursive( $t->element_id ) && $skip_empty ) {
  4046. continue;
  4047. }
  4048. $cached_object_key = $t->element_id . '#' . $el_type . '#0#' . $t->language_code;
  4049. wp_cache_set( $cached_object_key, $cached_object_key, 'icl_object_id' );
  4050. $translations[ $t->language_code ] = $t;
  4051. }
  4052. }
  4053. if($translations) {
  4054. wp_cache_set($cache_key, $translations, $cache_group);
  4055. }
  4056. return $translations;
  4057. }
  4058. static function get_original_element_id($element_id, $element_type = 'post_post', $skip_empty = false, $all_statuses = false, $skip_cache = false) {
  4059. $cache_key_args = array_filter( array( $element_id, $element_type, $skip_empty, $all_statuses ) );
  4060. $cache_key = md5(json_encode( $cache_key_args ));
  4061. $cache_group = 'original_element';
  4062. $temp_elements = $skip_cache ? false : wp_cache_get($cache_key, $cache_group);
  4063. if($temp_elements) return $temp_elements;
  4064. global $sitepress;
  4065. $original_element_id = false;
  4066. $trid = $sitepress->get_element_trid($element_id, $element_type);
  4067. if($trid) {
  4068. $element_translations = $sitepress->get_element_translations($trid, $element_type,$skip_empty,$all_statuses,$skip_cache);
  4069. foreach($element_translations as $element_translation) {
  4070. if($element_translation->original) {
  4071. $original_element_id = $element_translation->element_id;
  4072. break;
  4073. }
  4074. }
  4075. }
  4076. if($original_element_id) {
  4077. wp_cache_set($cache_key, $original_element_id, $cache_group);
  4078. }
  4079. return $original_element_id;
  4080. }
  4081. /**
  4082. * @param int $element_id Use term_taxonomy_id for taxonomies, post_id for posts
  4083. * @param string $el_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category, post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment')
  4084. *
  4085. * @return bool|mixed|null|string
  4086. */
  4087. function get_element_trid( $element_id, $el_type = 'post_post' ) {
  4088. $cache_key = $element_id . ':' . $el_type;
  4089. $cache_group = 'element_trid';
  4090. $temp_trid = wp_cache_get($cache_key, $cache_group);
  4091. if($temp_trid) return $temp_trid;
  4092. global $wpdb;
  4093. $trid_prepared = $wpdb->prepare( "SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", array( $element_id, $el_type ) );
  4094. $trid = $wpdb->get_var( $trid_prepared );
  4095. if($trid) {
  4096. wp_cache_add($cache_key, $trid, $cache_group);
  4097. }
  4098. return $trid;
  4099. }
  4100. /**
  4101. * @param int $trid
  4102. *
  4103. * @return int|bool
  4104. */
  4105. static function get_original_element_id_by_trid( $trid ) {
  4106. global $wpdb;
  4107. $original_element_id_prepared = $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND source_language_code IS NULL", $trid );
  4108. $element_id = $wpdb->get_var( $original_element_id_prepared );
  4109. return $element_id;
  4110. }
  4111. static function get_source_language_by_trid( $trid ) {
  4112. global $wpdb;
  4113. $source_language_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND source_language_code IS NULL", $trid );
  4114. $source_language = $wpdb->get_var( $source_language_prepared );
  4115. return $source_language;
  4116. }
  4117. /**
  4118. * @param int $element_id Use term_taxonomy_id for taxonomies, post_id for posts
  4119. * @param string $el_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category, post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment')
  4120. *
  4121. * @return null|string
  4122. */
  4123. function get_language_for_element( $element_id, $el_type = 'post_post' ) {
  4124. global $wpdb;
  4125. $cache_key_array = array( $element_id, $el_type );
  4126. $cache_key = md5( serialize( $cache_key_array ) );
  4127. $cache_group = 'get_language_for_element';
  4128. $cache_found = false;
  4129. $result = wp_cache_get( $cache_key, $cache_group, false, $cache_found );
  4130. if ( $cache_found ) {
  4131. return $result;
  4132. }
  4133. $language_for_element_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", array( $element_id, $el_type ) );
  4134. $result = $wpdb->get_var( $language_for_element_prepared );
  4135. if ( $result ) {
  4136. wp_cache_set( $cache_key, $result, $cache_group );
  4137. }
  4138. return $result;
  4139. }
  4140. /**
  4141. * @param string $el_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category, post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment')
  4142. * @param string $target_lang Target language code
  4143. * @param string $source_lang Source language code
  4144. *
  4145. * @return array
  4146. */
  4147. function get_elements_without_translations( $el_type, $target_lang, $source_lang )
  4148. {
  4149. global $wpdb;
  4150. // first get all the trids for the target languages
  4151. // These will be the trids that we don't want.
  4152. $sql = "SELECT
  4153. trid
  4154. FROM
  4155. {$wpdb->prefix}icl_translations
  4156. WHERE
  4157. language_code = '{$target_lang}'
  4158. AND element_type = '{$el_type}'
  4159. ";
  4160. $trids_for_target = $wpdb->get_col( $sql );
  4161. if ( sizeof( $trids_for_target ) > 0 ) {
  4162. $trids_for_target = join( ',', $trids_for_target );
  4163. $not_trids = 'AND trid NOT IN (' . $trids_for_target . ')';
  4164. } else {
  4165. $not_trids = '';
  4166. }
  4167. $join = $where = '';
  4168. // exclude trashed posts
  4169. if ( 0 === strpos( $el_type, 'post_' ) ) {
  4170. $join .= " JOIN {$wpdb->posts} ON {$wpdb->posts}.ID = {$wpdb->prefix}icl_translations.element_id";
  4171. $where .= " AND {$wpdb->posts}.post_status <> 'trash' AND {$wpdb->posts}.post_status <> 'auto-draft'";
  4172. }
  4173. // Now get all the elements that are in the source language that
  4174. // are not already translated into the target language.
  4175. $sql = "SELECT
  4176. element_id
  4177. FROM
  4178. {$wpdb->prefix}icl_translations
  4179. {$join}
  4180. WHERE
  4181. language_code = '{$source_lang}'
  4182. {$not_trids}
  4183. AND element_type= '{$el_type}'
  4184. {$where}
  4185. ";
  4186. return $wpdb->get_col( $sql );
  4187. }
  4188. /**
  4189. * @param string $selected_language
  4190. * @param string $default_language
  4191. * @param string $post_type
  4192. *
  4193. * @used_by SitePress:meta_box
  4194. *
  4195. * @return array
  4196. */
  4197. function get_posts_without_translations( $selected_language, $default_language, $post_type = 'post_post' )
  4198. {
  4199. global $wpdb;
  4200. $untranslated_ids = $this->get_elements_without_translations( $post_type, $selected_language, $default_language );
  4201. $untranslated = array();
  4202. foreach ( $untranslated_ids as $id ) {
  4203. $untranslated[ $id ] = $wpdb->get_var( "SELECT post_title FROM {$wpdb->prefix}posts WHERE ID = {$id}" );
  4204. }
  4205. return $untranslated;
  4206. }
  4207. static function get_orphan_translations($trid, $post_type = 'post', $source_language) {
  4208. global $sitepress, $wpdb;
  4209. $translations = $sitepress->get_element_translations($trid, 'post_' . $post_type);
  4210. if(count($translations) == 1) {
  4211. $sql = " SELECT trid, ";
  4212. $active_languages = $sitepress->get_active_languages();
  4213. $language_codes = array_keys($active_languages);
  4214. $sql_languages = array();
  4215. $sql_languages_having = array();
  4216. foreach($language_codes as $language_code) {
  4217. $sql_languages[] = "SUM(CASE language_code WHEN '" . esc_sql($language_code) . "' THEN 1 ELSE 0 END) AS `" . esc_sql($language_code) . '`';
  4218. if($language_code==$source_language) {
  4219. $sql_languages_having[] = '`' . $language_code . '`= 0';
  4220. }
  4221. }
  4222. $sql .= implode(',', $sql_languages);
  4223. $sql .= " FROM {$wpdb->prefix}icl_translations
  4224. WHERE element_type = %s ";
  4225. $sql .= 'GROUP BY trid ';
  4226. $sql .= 'HAVING ' . implode(' AND ', $sql_languages_having);
  4227. $sql .= " ORDER BY trid;";
  4228. $sql_prepared = $wpdb->prepare($sql, array('post_' . $post_type));
  4229. $trid_results = $wpdb->get_results($sql_prepared, 'ARRAY_A');
  4230. $trid_list = array_column($trid_results, 'trid');
  4231. if($trid_list) {
  4232. $sql = "SELECT trid AS value, CONCAT('[', t.language_code, '] ', (CASE p.post_title WHEN '' THEN CONCAT(LEFT(p.post_content, 30), '...') ELSE p.post_title END)) AS label
  4233. FROM {$wpdb->posts} p
  4234. INNER JOIN {$wpdb->prefix}icl_translations t
  4235. ON p.ID = t.element_id
  4236. WHERE t.element_type = %s
  4237. AND t.language_code <> %s
  4238. AND t.trid IN (" . implode(',', $trid_list) . ')';
  4239. $sql_prepared = $wpdb->prepare($sql, array('post_' . $post_type, $source_language));
  4240. $results = $wpdb->get_results($sql_prepared);
  4241. } else {
  4242. $results = array();
  4243. }
  4244. return $results;
  4245. }
  4246. return false;
  4247. }
  4248. /**
  4249. * @param WP_Post $post
  4250. */
  4251. function meta_box( $post ) {
  4252. if($this->settings['setup_complete']) {
  4253. if ( in_array( $post->post_type, array_keys( $this->get_translatable_documents() ) ) ) {
  4254. include ICL_PLUGIN_PATH . '/menu/post-menu.php';
  4255. }
  4256. }
  4257. }
  4258. function icl_get_metabox_states()
  4259. {
  4260. global $icl_meta_box_globals, $wpdb;
  4261. $translation = false;
  4262. $source_id = null;
  4263. $translated_id = null;
  4264. if ( sizeof( $icl_meta_box_globals[ 'translations' ] ) > 0 ) {
  4265. if ( !isset( $icl_meta_box_globals[ 'translations' ][ $icl_meta_box_globals[ 'selected_language' ] ] ) ) {
  4266. // We are creating a new translation
  4267. $translation = true;
  4268. // find the original
  4269. foreach ( $icl_meta_box_globals[ 'translations' ] as $trans_data ) {
  4270. if ( $trans_data->original == '1' ) {
  4271. $source_id = $trans_data->element_id;
  4272. break;
  4273. }
  4274. }
  4275. } else {
  4276. $trans_data = $icl_meta_box_globals[ 'translations' ][ $icl_meta_box_globals[ 'selected_language' ] ];
  4277. // see if this is an original or a translation.
  4278. if ( $trans_data->original == '0' ) {
  4279. // double check that it's not the original
  4280. // This is because the source_language_code field in icl_translations is not always being set to null.
  4281. $source_language_code = $wpdb->get_var( "SELECT source_language_code FROM {$wpdb->prefix}icl_translations WHERE translation_id = $trans_data->translation_id" );
  4282. $translation = !( $source_language_code == "" || $source_language_code == null );
  4283. if ( $translation ) {
  4284. $source_id = $icl_meta_box_globals[ 'translations' ][ $source_language_code ]->element_id;
  4285. $translated_id = $trans_data->element_id;
  4286. } else {
  4287. $source_id = $trans_data->element_id;
  4288. }
  4289. } else {
  4290. $source_id = $trans_data->element_id;
  4291. }
  4292. }
  4293. }
  4294. return array( $translation, $source_id, $translated_id );
  4295. }
  4296. function meta_box_config( $post )
  4297. {
  4298. global $iclTranslationManagement;
  4299. global $wp_taxonomies, $wp_post_types, $sitepress_settings;
  4300. if ( ! $this->settings[ 'setup_complete' ] ) {
  4301. return false;
  4302. }
  4303. echo '<div class="icl_form_success" style="display:none">' . __( 'Settings saved', 'sitepress' ) . '</div>';
  4304. $cp_editable = false;
  4305. $checked = false;
  4306. if ( !in_array( $post->post_type, array( 'post', 'page' ) ) ) {
  4307. if ( !isset( $iclTranslationManagement->settings[ 'custom_types_readonly_config' ][ $post->post_type ] ) || $iclTranslationManagement->settings[ 'custom_types_readonly_config' ][ $post->post_type ] !== 0 ) {
  4308. if ( in_array( $post->post_type, array_keys( $this->get_translatable_documents() ) ) ) {
  4309. $checked = ' checked="checked"';
  4310. $radio_disabled = isset( $iclTranslationManagement->settings[ 'custom_types_readonly_config' ][ $post->post_type ] ) ? 'disabled="disabled"' : '';
  4311. } else {
  4312. $checked = $radio_disabled = '';
  4313. }
  4314. if ( !$radio_disabled ) {
  4315. $cp_editable = true;
  4316. }
  4317. echo '<br style="line-height:8px;" /><label><input id="icl_make_translatable" type="checkbox" value="' . $post->post_type . '"' . $checked . $radio_disabled . '/>&nbsp;' . sprintf( __( "Make '%s' translatable", 'sitepress' ), $wp_post_types[ $post->post_type ]->labels->name ) . '</label><br style="line-height:8px;" />';
  4318. }
  4319. } else {
  4320. echo '<input id="icl_make_translatable" type="checkbox" checked="checked" value="' . $post->post_type . '" style="display:none" />';
  4321. $checked = true;
  4322. }
  4323. echo '<br clear="all" /><span id="icl_mcs_details">';
  4324. if ( $checked ) {
  4325. //echo '<div style="width:49%;float:left;min-width:265px;margin-right:5px;margin-top:3px;">';
  4326. $custom_taxonomies = array_diff( get_object_taxonomies( $post->post_type ), array( 'post_tag', 'category', 'nav_menu', 'link_category', 'post_format' ) );
  4327. if ( !empty( $custom_taxonomies ) ) {
  4328. ?>
  4329. <table class="widefat">
  4330. <thead>
  4331. <tr>
  4332. <th colspan="2"><?php _e( 'Custom taxonomies', 'sitepress' ); ?></th>
  4333. </tr>
  4334. </thead>
  4335. <tbody>
  4336. <?php foreach ( $custom_taxonomies as $ctax ): ?>
  4337. <?php
  4338. $checked1 = !empty( $sitepress_settings[ 'taxonomies_sync_option' ][ $ctax ] ) ? ' checked="checked"' : '';
  4339. $checked0 = empty( $sitepress_settings[ 'taxonomies_sync_option' ][ $ctax ] ) ? ' checked="checked"' : '';
  4340. $radio_disabled = isset( $iclTranslationManagement->settings[ 'taxonomies_readonly_config' ][ $ctax ] ) ? ' disabled="disabled"' : '';
  4341. ?>
  4342. <tr>
  4343. <td><?php echo $wp_taxonomies[ $ctax ]->labels->name ?></td>
  4344. <td align="right">
  4345. <label><input name="icl_mcs_custom_taxs_<?php echo $ctax ?>" class="icl_mcs_custom_taxs" type="radio"
  4346. value="<?php echo $ctax ?>" <?php echo $checked1; ?><?php echo $radio_disabled ?> />&nbsp;<?php _e( 'Translate', 'sitepress' ) ?></label>
  4347. <label><input name="icl_mcs_custom_taxs_<?php echo $ctax ?>" type="radio" value="0" <?php echo $checked0; ?><?php echo $radio_disabled ?> />&nbsp;<?php _e( 'Do nothing', 'sitepress' ) ?></label>
  4348. </td>
  4349. </tr>
  4350. <?php endforeach; ?>
  4351. </tbody>
  4352. </table>
  4353. <br/>
  4354. <?php
  4355. }
  4356. //echo '</div><div style="width:50%;float:left;min-width:265px;margin-top:3px;">';
  4357. if ( defined( 'WPML_TM_VERSION' ) ) {
  4358. $custom_keys = (array)get_post_custom_keys( $post->ID );
  4359. $cf_keys_exceptions = array(
  4360. '_edit_last', '_edit_lock', '_wp_page_template', '_wp_attachment_metadata', '_icl_translator_note', '_alp_processed', '_pingme', '_encloseme', '_icl_lang_duplicate_of', '_wpml_media_duplicate', '_wpml_media_featured',
  4361. '_thumbnail_id'
  4362. );
  4363. $custom_keys = array_diff( $custom_keys, $cf_keys_exceptions );
  4364. $cf_settings_read_only = isset( $iclTranslationManagement->settings[ 'custom_fields_readonly_config' ] ) ? (array)$iclTranslationManagement->settings[ 'custom_fields_readonly_config' ] : array();
  4365. $cf_settings = isset( $iclTranslationManagement->settings[ 'custom_fields_translation' ] ) ? $iclTranslationManagement->settings[ 'custom_fields_translation' ] : array();
  4366. if ( !empty( $custom_keys ) ) {
  4367. ?>
  4368. <table class="widefat">
  4369. <thead>
  4370. <tr>
  4371. <th colspan="2"><?php _e( 'Custom fields', 'sitepress' ); ?></th>
  4372. </tr>
  4373. </thead>
  4374. <tbody>
  4375. <?php
  4376. foreach ( $custom_keys as $cfield ) {
  4377. if ( empty( $cf_settings[ $cfield ] ) || $cf_settings[ $cfield ] != 3 ) {
  4378. $radio_disabled = in_array( $cfield, $cf_settings_read_only ) ? 'disabled="disabled"' : '';
  4379. $checked0 = empty( $cf_settings[ $cfield ] ) ? ' checked="checked"' : '';
  4380. $checked1 = isset( $cf_settings[ $cfield ] ) && $cf_settings[ $cfield ] == 1 ? ' checked="checked"' : '';
  4381. $checked2 = isset( $cf_settings[ $cfield ] ) && $cf_settings[ $cfield ] == 2 ? ' checked="checked"' : '';
  4382. ?>
  4383. <tr>
  4384. <td><?php echo $cfield; ?></td>
  4385. <td align="right">
  4386. <label><input class="icl_mcs_cfs" name="icl_mcs_cf_<?php echo base64_encode( $cfield ); ?> " type="radio"
  4387. value="0" <?php echo $radio_disabled . $checked0 ?> />&nbsp;<?php _e( "Don't translate", 'sitepress' ) ?></label>
  4388. <label><input class="icl_mcs_cfs" name="icl_mcs_cf_<?php echo base64_encode( $cfield ); ?> " type="radio" value="1" <?php echo $radio_disabled . $checked1 ?> />&nbsp;<?php _e( "Copy", 'sitepress' ) ?>
  4389. </label>
  4390. <label><input class="icl_mcs_cfs" name="icl_mcs_cf_<?php echo base64_encode( $cfield ); ?> " type="radio" value="2" <?php echo $radio_disabled . $checked2 ?> />&nbsp;<?php _e( "Translate", 'sitepress' ) ?>
  4391. </label>
  4392. </td>
  4393. </tr>
  4394. <?php
  4395. }
  4396. }
  4397. ?>
  4398. </tbody>
  4399. </table>
  4400. <br/>
  4401. <?php
  4402. }
  4403. }
  4404. //echo '</div><br clear="all" />';
  4405. if ( !empty( $custom_taxonomies ) || !empty( $custom_keys ) ) {
  4406. echo '<small>' . __( 'Note: Custom taxonomies and custom fields are shared across different post types.', 'sitepress' ) . '</small>';
  4407. }
  4408. }
  4409. echo '</span>';
  4410. if ( $cp_editable || !empty( $custom_taxonomies ) || !empty( $custom_keys ) ) {
  4411. 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" />';
  4412. wp_nonce_field( 'icl_mcs_inline_nonce', '_icl_nonce_imi' );
  4413. } else {
  4414. _e( 'Nothing to configure.', 'sitepress' );
  4415. }
  4416. }
  4417. function pre_get_posts( $wpq )
  4418. {
  4419. // case of internal links list
  4420. //
  4421. if ( isset( $_POST[ 'action' ] ) && 'wp-link-ajax' == $_POST[ 'action' ] ) {
  4422. $default_language = $this->get_default_language();
  4423. if ( !empty( $_SERVER[ 'HTTP_REFERER' ] ) ) {
  4424. $parts = parse_url( $_SERVER[ 'HTTP_REFERER' ] );
  4425. parse_str( strval( $parts[ 'query' ] ), $query );
  4426. $lang = isset( $query[ 'lang' ] ) ? $query[ 'lang' ] : $default_language;
  4427. } else $lang = $default_language;
  4428. $this->this_lang = $lang;
  4429. $wpq->query_vars[ 'suppress_filters' ] = false;
  4430. }
  4431. if ($this->is_gallery_on_root_page($wpq)) {
  4432. $wpq->query_vars['page_id'] = 0;
  4433. $wpq->query['page_id'] = 0;
  4434. }
  4435. return $wpq;
  4436. }
  4437. function is_gallery_on_root_page( $wpq ) {
  4438. // are we on root page and we are searching for attachments to gallery on it?
  4439. if ( isset( $this->settings[ 'urls' ][ 'show_on_root' ] ) &&
  4440. $this->settings[ 'urls' ][ 'show_on_root' ] == 'page' &&
  4441. isset( $this->settings[ 'urls' ][ 'root_page' ] ) &&
  4442. isset( $wpq->query_vars[ 'page_id' ] ) &&
  4443. $wpq->query_vars[ 'page_id' ] > 0 &&
  4444. $wpq->query_vars[ 'page_id' ] == $this->settings[ 'urls' ][ 'root_page' ] &&
  4445. isset( $wpq->query_vars[ 'post_type' ] ) &&
  4446. $wpq->query_vars[ 'post_type' ] == 'attachment'
  4447. ) {
  4448. return true;
  4449. }
  4450. return false;
  4451. }
  4452. /**
  4453. * @param $join string
  4454. * @param $query WP_Query
  4455. *
  4456. * @return string
  4457. */
  4458. function posts_join_filter( $join, $query )
  4459. {
  4460. global $wpdb, $pagenow, $wp_taxonomies, $sitepress_settings;
  4461. $attachment_is_translatable = $this->is_translated_post_type( 'attachment' );
  4462. if ( (($pagenow == 'upload.php' || $pagenow == 'media-upload.php' || $query->is_attachment()) && !$attachment_is_translatable) || ( isset( $query->queried_object ) && isset( $query->queried_object->ID ) && $query->queried_object->ID == $sitepress_settings[ 'urls' ][ 'root_page' ] ) ) {
  4463. return $join;
  4464. }
  4465. // determine post type
  4466. $debug_backtrace = $this->get_backtrace( 0, true, false ); //Limit to a maximum level?
  4467. $post_type = false;
  4468. foreach ( $debug_backtrace as $o ) {
  4469. if ( $o[ 'function' ] == 'apply_filters_ref_array' && $o[ 'args' ][ 0 ] == 'posts_join' ) {
  4470. $post_type = esc_sql( $o[ 'args' ][ 1 ][ 1 ]->query_vars[ 'post_type' ] );
  4471. break;
  4472. }
  4473. }
  4474. if ( $post_type == 'any' || 'all' == $this->this_lang ) {
  4475. $left_join = "LEFT";
  4476. } else {
  4477. $left_join = "";
  4478. }
  4479. if ( is_array( $post_type ) ) {
  4480. $post_types = array();
  4481. foreach ( $post_type as $ptype ) {
  4482. if ( $this->is_translated_post_type( $ptype ) ) {
  4483. $post_types[ ] = esc_sql( 'post_' . $ptype );
  4484. }
  4485. }
  4486. if ( !empty( $post_types ) ) {
  4487. $join .= " {$left_join} JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->posts}.ID = t.element_id
  4488. AND t.element_type IN ('" . join( "','", $post_types ) . "') JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active=1";
  4489. }
  4490. } elseif ( $post_type ) {
  4491. if ( $this->is_translated_post_type( $post_type ) ) {
  4492. $join .= " {$left_join} JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->posts}.ID = t.element_id
  4493. AND t.element_type = 'post_{$post_type}' JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active=1";
  4494. } elseif ( $post_type == 'any' ) {
  4495. $join .= " {$left_join} JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->posts}.ID = t.element_id
  4496. AND t.element_type LIKE 'post\\_%' {$left_join} JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active=1";
  4497. }
  4498. } else {
  4499. if ( $query->is_tax() && $query->is_main_query() ) {
  4500. $tax = $query->get( 'taxonomy' );
  4501. $taxonomy_post_types = $wp_taxonomies[ $tax ]->object_type;
  4502. foreach ( $taxonomy_post_types as $k => $v ) {
  4503. if ( !$this->is_translated_post_type( $v ) ) {
  4504. unset( $taxonomy_post_types[ $k ] );
  4505. }
  4506. }
  4507. } else {
  4508. $taxonomy_post_types = array_keys( $this->get_translatable_documents( false ) );
  4509. }
  4510. if ( !empty( $taxonomy_post_types ) ) {
  4511. foreach ( $taxonomy_post_types as $k => $v ) {
  4512. $taxonomy_post_types[ $k ] = 'post_' . $v;
  4513. }
  4514. $post_types = "'" . join( "','", $taxonomy_post_types ) . "'";
  4515. $join .= " {$left_join} JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->posts}.ID = t.element_id
  4516. AND t.element_type IN ({$post_types}) JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active=1";
  4517. }
  4518. }
  4519. return $join;
  4520. }
  4521. /**
  4522. * @param string $where
  4523. * @param WP_Query $query
  4524. *
  4525. * @return string
  4526. */
  4527. function posts_where_filter( $where, $query )
  4528. {
  4529. global $pagenow, $wp_taxonomies, $sitepress, $sitepress_settings;
  4530. //exceptions
  4531. $post_type = false;
  4532. if ( isset( $query->queried_object ) && isset( $query->queried_object->ID ) && $query->queried_object->ID == $sitepress_settings[ 'urls' ][ 'root_page' ] ) {
  4533. return $where;
  4534. }
  4535. // determine post type
  4536. $debug_backtrace = $this->get_backtrace( 0, true, false ); //Limit to a maximum level?
  4537. foreach ( $debug_backtrace as $o ) {
  4538. if ( $o[ 'function' ] == 'apply_filters_ref_array' && $o[ 'args' ][ 0 ] == 'posts_where' ) {
  4539. $post_type = $o[ 'args' ][ 1 ][ 1 ]->query_vars[ 'post_type' ];
  4540. break;
  4541. }
  4542. }
  4543. // case of taxonomy archive
  4544. if ( empty( $post_type ) && $query->is_tax() ) {
  4545. $tax = $query->get( 'taxonomy' );
  4546. $post_type = $wp_taxonomies[ $tax ]->object_type;
  4547. foreach ( $post_type as $k => $v ) {
  4548. if ( !$this->is_translated_post_type( $v ) ) {
  4549. unset( $post_type[ $k ] );
  4550. }
  4551. }
  4552. if ( empty( $post_type ) ) {
  4553. return $where;
  4554. } // don't filter
  4555. }
  4556. if ( !$post_type ) {
  4557. $post_type = 'post';
  4558. }
  4559. if ( is_array( $post_type ) && !empty( $post_type ) ) {
  4560. $none_translated = true;
  4561. foreach ( $post_type as $ptype ) {
  4562. if ( $this->is_translated_post_type( $ptype ) ) {
  4563. $none_translated = false;
  4564. }
  4565. }
  4566. if ( $none_translated ) {
  4567. return $where;
  4568. }
  4569. } else {
  4570. if ( !$this->is_translated_post_type( $post_type ) && 'any' != $post_type ) {
  4571. return $where;
  4572. }
  4573. }
  4574. $attachment_is_translatable = $sitepress->is_translated_post_type( 'attachment' );
  4575. if ( ($pagenow == 'upload.php' || $pagenow == 'media-upload.php' || $query->is_attachment()) && !$attachment_is_translatable) {
  4576. return $where;
  4577. }
  4578. $current_language = $sitepress->get_current_language();
  4579. $requested_id = false;
  4580. // Fix for when $sitepress->get_current_language() does not return the correct value (e.g. when request is made for an attachment, an iframe or an ajax call)
  4581. if ( isset( $_REQUEST[ 'attachment_id' ] ) && $_REQUEST[ 'attachment_id' ] ) {
  4582. $requested_id = $_REQUEST[ 'attachment_id' ];
  4583. }
  4584. if ( isset( $_REQUEST[ 'post_id' ] ) && $_REQUEST[ 'post_id' ] ) {
  4585. $requested_id = $_REQUEST[ 'post_id' ];
  4586. }
  4587. if($requested_id) {
  4588. $post_type = get_post_type( $requested_id );
  4589. $current_language = $sitepress->get_language_for_element( $requested_id, 'post_' . $post_type );
  4590. if(!$current_language) {
  4591. $current_language = $sitepress->get_current_language();
  4592. }
  4593. }
  4594. if ( 'all' != $this->this_lang ) {
  4595. if ( 'any' == $post_type ) {
  4596. $condition = " AND (t.language_code='" . esc_sql( $current_language ) . "' OR t.language_code IS NULL )";
  4597. } else {
  4598. $condition = " AND t.language_code='" . esc_sql( $current_language ) . "'";
  4599. }
  4600. } else {
  4601. $condition = '';
  4602. }
  4603. $where .= $condition;
  4604. return $where;
  4605. }
  4606. function comment_feed_join( $join )
  4607. {
  4608. global $wpdb, $wp_query;
  4609. $type = $wp_query->query_vars[ 'post_type' ] ? esc_sql( $wp_query->query_vars[ 'post_type' ] ) : 'post';
  4610. $wp_query->query_vars[ 'is_comment_feed' ] = true;
  4611. $join .= " JOIN {$wpdb->prefix}icl_translations t ON {$wpdb->comments}.comment_post_ID = t.element_id
  4612. AND t.element_type='post_{$type}' AND t.language_code='" . esc_sql( $this->this_lang ) . "'";
  4613. return $join;
  4614. }
  4615. function comments_clauses( $clauses, $obj )
  4616. {
  4617. global $wpdb;
  4618. if ( isset( $obj->query_vars[ 'post_id' ] ) ) {
  4619. $post_id = $obj->query_vars[ 'post_id' ];
  4620. } elseif ( isset( $obj->query_vars[ 'post_ID' ] ) ) {
  4621. $post_id = $obj->query_vars[ 'post_ID' ];
  4622. }
  4623. if ( !empty( $post_id ) ) {
  4624. $post = get_post( $post_id );
  4625. if ( !$this->is_translated_post_type( $post->post_type ) ) {
  4626. return $clauses;
  4627. }
  4628. }
  4629. $current_language = $this->get_current_language();
  4630. if ( $current_language != 'all' ) {
  4631. $clauses[ 'join' ] .= " JOIN {$wpdb->prefix}icl_translations icltr1 ON
  4632. icltr1.element_id = {$wpdb->comments}.comment_ID
  4633. JOIN {$wpdb->prefix}icl_translations icltr2 ON
  4634. icltr2.element_id = {$wpdb->comments}.comment_post_ID
  4635. ";
  4636. $clauses[ 'where' ] .= " AND icltr1.element_type = 'comment'
  4637. AND icltr1.language_code = '" . $current_language . "'
  4638. AND icltr2.language_code = '" . $current_language . "'
  4639. AND icltr2.element_type LIKE 'post\\_%' ";
  4640. }
  4641. return $clauses;
  4642. }
  4643. function language_filter()
  4644. {
  4645. require_once ICL_PLUGIN_PATH . '/inc/cache.php';
  4646. global $wpdb;
  4647. $type = isset( $_GET[ 'post_type' ] ) ? $_GET[ 'post_type' ] : 'post';
  4648. if ( !in_array( $type, array( 'post', 'page' ) ) && !in_array( $type, array_keys( $this->get_translatable_documents() ) ) ) {
  4649. return;
  4650. }
  4651. $active_languages = $this->get_active_languages();
  4652. $post_status = get_query_var( 'post_status' );
  4653. if ( is_string( $post_status ) ) {
  4654. $post_status = $post_status ? array( $post_status ) : array();
  4655. }
  4656. $key = join( ',', $post_status );
  4657. if ( $key ) {
  4658. $key = '#' . $key;
  4659. }
  4660. $languages = icl_cache_get( $type . 's_per_language' . $key );
  4661. if ( !$languages ) {
  4662. $extra_conditions = "";
  4663. if ( $post_status ) {
  4664. $extra_conditions .= apply_filters( '_icl_posts_language_count_status', " AND post_status IN('" . join( "','", $post_status ) . "') " );
  4665. }
  4666. if ( $post_status != array( 'trash' ) ) {
  4667. $extra_conditions .= " AND post_status <> 'trash'";
  4668. }
  4669. // dont count auto drafts
  4670. $extra_conditions .= " AND post_status <> 'auto-draft'";
  4671. // only active language
  4672. $extra_conditions .= " AND t.language_code IN ('" . join( "','", array_keys( $active_languages ) ) . "') ";
  4673. $res = $wpdb->get_results( "
  4674. SELECT language_code, COUNT(p.ID) AS c FROM {$wpdb->prefix}icl_translations t
  4675. JOIN {$wpdb->posts} p ON t.element_id=p.ID
  4676. JOIN {$wpdb->prefix}icl_languages l ON t.language_code=l.code AND l.active = 1
  4677. WHERE p.post_type='{$type}' AND t.element_type='post_{$type}' {$extra_conditions}
  4678. GROUP BY language_code
  4679. " );
  4680. $languages[ 'all' ] = 0;
  4681. foreach ( $res as $r ) {
  4682. $languages[ $r->language_code ] = $r->c;
  4683. $languages[ 'all' ] += $r->c;
  4684. }
  4685. icl_cache_set( $type . 's_per_language' . $key, $languages );
  4686. }
  4687. $active_languages[ ] = array( 'code' => 'all', 'display_name' => __( 'All languages', 'sitepress' ) );
  4688. $as = array();
  4689. foreach ( $active_languages as $lang ) {
  4690. if ( $lang[ 'code' ] == $this->this_lang ) {
  4691. $px = '<strong>';
  4692. $sx = ' <span class="count">(' . @intval( $languages[ $lang[ 'code' ] ] ) . ')<\/span><\/strong>';
  4693. } elseif ( !isset( $languages[ $lang[ 'code' ] ] ) ) {
  4694. $px = '<span>';
  4695. $sx = '<\/span>';
  4696. } else {
  4697. if ( $post_status ) {
  4698. $px = '<a href="?post_type=' . $type . '&post_status=' . join( ',', $post_status ) . '&lang=' . $lang[ 'code' ] . '">';
  4699. } else {
  4700. $px = '<a href="?post_type=' . $type . '&lang=' . $lang[ 'code' ] . '">';
  4701. }
  4702. $sx = '<\/a> <span class="count">(' . intval( $languages[ $lang[ 'code' ] ] ) . ')<\/span>';
  4703. }
  4704. $as[ ] = $px . $lang[ 'display_name' ] . $sx;
  4705. }
  4706. $allas = join( ' | ', $as );
  4707. if ( empty( $this->settings[ 'hide_how_to_translate' ] ) && $type == 'page' && !$this->get_icl_translation_enabled() ) {
  4708. $prot_link = '<span id="icl_how_to_translate_link" class="button" style="padding-right:3px;" ><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="https://wpml.org/?page_id=3416">' . __( 'How to translate', 'sitepress' ) . '</a><a href="#" title="' . esc_attr__( 'hide this', 'sitepress' ) . '" onclick=" if(confirm(\\\'' . __( 'Are you sure you want to remove this button?', 'sitepress' ) . '\\\')) jQuery.ajax({url:icl_ajx_url,type:\\\'POST\\\',data:{icl_ajx_action:\\\'update_option\\\', option:\\\'hide_how_to_translate\\\',value:1,_icl_nonce:\\\'' . wp_create_nonce( 'update_option_nonce' ) . '\\\'},success:function(){jQuery(\\\'#icl_how_to_translate_link\\\').fadeOut()}});return false;" style="outline:none;"><img src="' . ICL_PLUGIN_URL . '/res/img/close2.png" width="10" height="10" style="border:none" alt="' . esc_attr__( 'hide', 'sitepress' ) . '" /><\/a>' . '<\/span>';
  4709. } else {
  4710. $prot_link = '';
  4711. }
  4712. ?>
  4713. <script type="text/javascript">
  4714. jQuery(".subsubsub").append('<br /><span id="icl_subsubsub"><?php echo $allas ?></span><br /><?php echo $prot_link ?>');
  4715. </script>
  4716. <?php
  4717. }
  4718. function exclude_other_language_pages2( $arr )
  4719. {
  4720. $new_arr = $arr;
  4721. $current_language = $this->get_current_language();
  4722. if ( $current_language != 'all' ) {
  4723. $cache_key = md5(json_encode($new_arr));
  4724. $cache_group = 'exclude_other_language_pages2';
  4725. $found = false;
  4726. $result = wp_cache_get($cache_key, $cache_group, false, $found);
  4727. if(!$found) {
  4728. global $wpdb;
  4729. if ( is_array( $new_arr ) && !empty( $new_arr[ 0 ]->post_type ) ) {
  4730. $post_type = $new_arr[ 0 ]->post_type;
  4731. } else {
  4732. $post_type = 'page';
  4733. }
  4734. $filtered_pages = array();
  4735. // grab list of pages NOT in the current language
  4736. $excl_pages = $wpdb->get_col( $wpdb->prepare( "
  4737. SELECT p.ID FROM {$wpdb->posts} p
  4738. JOIN {$wpdb->prefix}icl_translations t ON p.ID = t.element_id
  4739. WHERE t.element_type=%s AND p.post_type=%s AND t.language_code <> %s
  4740. ", 'post_' . $post_type, $post_type, $current_language ) );
  4741. // exclude them from the result set
  4742. if ( !empty( $new_arr ) ) {
  4743. foreach ( $new_arr as $page ) {
  4744. if ( !in_array( $page->ID, $excl_pages ) ) {
  4745. $filtered_pages[ ] = $page;
  4746. }
  4747. }
  4748. $new_arr = $filtered_pages;
  4749. }
  4750. wp_cache_set($cache_key, $new_arr, $cache_group);
  4751. } else {
  4752. $new_arr = $result;
  4753. }
  4754. }
  4755. return $new_arr;
  4756. }
  4757. function wp_dropdown_pages( $output )
  4758. {
  4759. global $wpdb;
  4760. if ( isset( $_POST[ 'lang_switch' ] ) ) {
  4761. $post_id = esc_sql( $_POST[ 'lang_switch' ] );
  4762. $lang = esc_sql( strip_tags( $_GET[ 'lang' ] ) );
  4763. $parent = $wpdb->get_var( $wpdb->prepare( "SELECT post_parent FROM {$wpdb->posts} WHERE ID=%d", $post_id ) );
  4764. if ( $parent ) {
  4765. $trid = $wpdb->get_var( "SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id='{$parent}' AND element_type='post_page'" );
  4766. $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}'" );
  4767. if ( $translated_parent_id ) {
  4768. $output = str_replace( 'selected="selected"', '', $output );
  4769. $output = str_replace( 'value="' . $translated_parent_id . '"', 'value="' . $translated_parent_id . '" selected="selected"', $output );
  4770. }
  4771. }
  4772. } elseif ( isset( $_GET[ 'lang' ] ) && isset( $_GET[ 'trid' ] ) ) {
  4773. $lang = esc_sql( strip_tags( $_GET[ 'lang' ] ) );
  4774. $trid = esc_sql( $_GET[ 'trid' ] );
  4775. $post_type = isset( $_GET[ 'post_type' ] ) ? $_GET[ 'post_type' ] : 'page';
  4776. $elements_id = $wpdb->get_col( $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations
  4777. WHERE trid=%d AND element_type=%s AND element_id IS NOT NULL", $trid, 'post_' . $post_type ) );
  4778. $translated_parent_id = 0;
  4779. foreach ( $elements_id as $element_id ) {
  4780. $parent = $wpdb->get_var( $wpdb->prepare( "SELECT post_parent FROM {$wpdb->posts} WHERE ID=%d", $element_id ) );
  4781. $trid = $wpdb->get_var( $wpdb->prepare( "
  4782. SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", $parent, 'post_' . $post_type ) );
  4783. $translated_parent_id = $wpdb->get_var( $wpdb->prepare( "
  4784. SELECT element_id FROM {$wpdb->prefix}icl_translations
  4785. WHERE trid=%d AND element_type=%s AND language_code=%s", $trid, 'post_' . $post_type, $lang ) );
  4786. if ( $translated_parent_id ) {
  4787. break;
  4788. }
  4789. }
  4790. if ( $translated_parent_id ) {
  4791. $output = str_replace( 'selected="selected"', '', $output );
  4792. $output = str_replace( 'value="' . $translated_parent_id . '"', 'value="' . $translated_parent_id . '" selected="selected"', $output );
  4793. }
  4794. }
  4795. if ( !$output ) {
  4796. $output = '<select id="parent_id"><option value="">' . __( 'Main Page (no parent)', 'sitepress' ) . '</option></select>';
  4797. }
  4798. return $output;
  4799. }
  4800. function edit_term_form( $term )
  4801. {
  4802. include ICL_PLUGIN_PATH . '/menu/taxonomy-menu.php';
  4803. }
  4804. function wp_dropdown_cats_select_parent( $html )
  4805. {
  4806. global $wpdb;
  4807. if ( isset( $_GET[ 'trid' ] ) ) {
  4808. $element_type = $taxonomy = isset( $_GET[ 'taxonomy' ] ) ? $_GET[ 'taxonomy' ] : 'post_tag';
  4809. $icl_element_type = 'tax_' . $element_type;
  4810. $trid = intval( $_GET[ 'trid' ] );
  4811. $source_lang = isset( $_GET[ 'source_lang' ] ) ? $_GET[ 'source_lang' ] : $this->get_default_language();
  4812. $parent = $wpdb->get_var( "
  4813. SELECT parent
  4814. FROM {$wpdb->term_taxonomy} tt
  4815. JOIN {$wpdb->prefix}icl_translations tr ON tr.element_id=tt.term_taxonomy_id
  4816. AND tr.element_type='{$icl_element_type}' AND tt.taxonomy='{$taxonomy}'
  4817. WHERE trid='{$trid}' AND tr.language_code='{$source_lang}'
  4818. " );
  4819. if ( $parent ) {
  4820. $parent = icl_object_id( $parent, $element_type );
  4821. $html = str_replace( 'value="' . $parent . '"', 'value="' . $parent . '" selected="selected"', $html );
  4822. }
  4823. }
  4824. return $html;
  4825. }
  4826. function add_language_selector_to_page( $active_languages, $selected_language, $translations, $element_id, $type )
  4827. {
  4828. ?>
  4829. <div id="icl_tax_menu" style="display:none">
  4830. <div id="dashboard-widgets" class="metabox-holder">
  4831. <div class="postbox-container" style="width: 99%;line-height:normal;">
  4832. <div id="icl_<?php echo $type ?>_lang" class="postbox" style="line-height:normal;">
  4833. <h3 class="hndle">
  4834. <span><?php echo __( 'Language', 'sitepress' ) ?></span>
  4835. </h3>
  4836. <div class="inside" style="padding: 10px;">
  4837. <select name="icl_<?php echo $type ?>_language">
  4838. <?php
  4839. foreach ( $active_languages as $lang ) {
  4840. if ( $lang[ 'code' ] == $selected_language ) {
  4841. ?>
  4842. <option value="<?php echo $selected_language ?>" selected="selected"><?php echo $lang[ 'display_name' ] ?></option>
  4843. <?php
  4844. }
  4845. }
  4846. ?>
  4847. <?php foreach ( $active_languages as $lang ): ?>
  4848. <?php if ( $lang[ 'code' ] == $selected_language || ( isset( $translations[ $lang[ 'code' ] ]->element_id ) && $translations[ $lang[ 'code' ] ]->element_id != $element_id ) ) {
  4849. continue;
  4850. } ?>
  4851. <option value="<?php echo $lang[ 'code' ] ?>"<?php if ( $selected_language == $lang[ 'code' ] ): ?> selected="selected"<?php endif; ?>><?php echo $lang[ 'display_name' ] ?></option>
  4852. <?php endforeach; ?>
  4853. </select>
  4854. <?php
  4855. }
  4856. function get_category_name( $id )
  4857. {
  4858. _deprecated_function( __FUNCTION__, '2.3.1', 'get_cat_name()' );
  4859. global $wpdb;
  4860. $term_id = $wpdb->get_var( "SELECT term_id FROM {$wpdb->prefix}term_taxonomy WHERE term_taxonomy_id = {$id}" );
  4861. if ( $term_id ) {
  4862. return $wpdb->get_var( "SELECT name FROM {$wpdb->prefix}terms WHERE term_id = {$term_id}" );
  4863. } else {
  4864. return null;
  4865. }
  4866. }
  4867. function add_translation_of_selector_to_page( $trid, $selected_language, $default_language, $source_language, $untranslated_ids, $element_id, $type )
  4868. {
  4869. global $wpdb;
  4870. if(!$this->settings['setup_complete']){
  4871. return false;
  4872. }
  4873. ?>
  4874. <input type="hidden" name="icl_trid" value="<?php echo $trid ?>"/>
  4875. <?php
  4876. if ( $selected_language != $default_language && 'all' != $this->get_current_language() ) {
  4877. ?>
  4878. <br/><br/>
  4879. <?php echo __( 'This is a translation of', 'sitepress' ); ?><br/>
  4880. <select name="icl_translation_of" id="icl_translation_of"<?php if ( ( !isset( $_GET[ 'action' ] ) || $_GET[ 'action' ] != 'edit' ) && $trid ) {
  4881. echo " disabled";
  4882. } ?>>
  4883. <?php
  4884. if ( !$source_language || $source_language == $default_language ) {
  4885. if ( $trid ) {
  4886. ?>
  4887. <option value="none"><?php echo __( '--None--', 'sitepress' ) ?></option>
  4888. <?php
  4889. //get source
  4890. $src_language_id = $wpdb->get_var( $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND language_code=%s", $trid, $default_language ) );
  4891. if ( !$src_language_id ) {
  4892. // select the first id found for this trid
  4893. $src_language_id = $wpdb->get_var( $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d", $trid ) );
  4894. }
  4895. if ( $src_language_id && $src_language_id != $element_id ) {
  4896. $term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id=%d", $src_language_id ) );
  4897. $src_language_title = $wpdb->get_var( $wpdb->prepare( "SELECT name FROM {$wpdb->terms} WHERE term_id=%d", $term_id ) );
  4898. }
  4899. if ( !empty( $src_language_title ) ) {
  4900. ?>
  4901. <option value="<?php echo $src_language_id; ?>" selected="selected"><?php echo $src_language_title; ?></option>
  4902. <?php
  4903. }
  4904. } else {
  4905. ?>
  4906. <option value="none" selected="selected"><?php echo __( '--None--', 'sitepress' ); ?></option>
  4907. <?php
  4908. }
  4909. foreach ( $untranslated_ids as $translation_of_id ) {
  4910. $title = $wpdb->get_var( $wpdb->prepare( "SELECT name FROM {$wpdb->terms} WHERE term_id=%d", $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id=%d", $translation_of_id ) ) ) );
  4911. if ( !empty( $title ) ) {
  4912. ?>
  4913. <option value="<?php echo $translation_of_id; ?>"><?php echo $title; ?></option>
  4914. <?php
  4915. }
  4916. }
  4917. } else {
  4918. if ( $trid ) {
  4919. $src_language_title = false;
  4920. // add the source language
  4921. $src_language_id = $wpdb->get_var( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid={$trid} AND language_code='{$source_language}'" );
  4922. if ( $src_language_id ) {
  4923. $term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id=%d", $src_language_id ) );
  4924. $src_language_title = $wpdb->get_var( $wpdb->prepare( "SELECT name FROM {$wpdb->terms} WHERE term_id=%d", $term_id ) );
  4925. }
  4926. if ( $src_language_title ) {
  4927. ?>
  4928. <option value="<?php echo $src_language_id; ?>" selected="selected"><?php echo $src_language_title; ?></option>
  4929. <?php
  4930. }
  4931. } else {
  4932. ?>
  4933. <option value="none" selected="selected"><?php echo __( '--None--', 'sitepress' ); ?></option>
  4934. <?php
  4935. }
  4936. }
  4937. ?>
  4938. </select>
  4939. <?php
  4940. }
  4941. }
  4942. function add_translate_options( $trid, $active_languages, $selected_language, $translations, $type )
  4943. {
  4944. if ( $trid && isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'edit' ):
  4945. if(!$this->settings['setup_complete']){
  4946. return false;
  4947. }
  4948. ?>
  4949. <div id="icl_translate_options">
  4950. <?php
  4951. // count number of translated and un-translated pages.
  4952. $translations_found = 0;
  4953. $untranslated_found = 0;
  4954. foreach ( $active_languages as $lang ) {
  4955. if ( $selected_language == $lang[ 'code' ] ) {
  4956. continue;
  4957. }
  4958. if ( isset( $translations[ $lang[ 'code' ] ]->element_id ) ) {
  4959. $translations_found += 1;
  4960. } else {
  4961. $untranslated_found += 1;
  4962. }
  4963. }
  4964. ?>
  4965. <?php if ( $untranslated_found > 0 ): ?>
  4966. <table cellspacing="1" class="icl_translations_table" style="min-width:200px;margin-top:10px;">
  4967. <thead>
  4968. <tr>
  4969. <th colspan="2" style="padding:4px;background-color:#DFDFDF"><b><?php _e( 'Translate', 'sitepress' ); ?></b></th>
  4970. </tr>
  4971. </thead>
  4972. <tbody>
  4973. <?php foreach ( $active_languages as $lang ): if ( $selected_language == $lang[ 'code' ] ) {
  4974. continue;
  4975. } ?>
  4976. <tr>
  4977. <?php if ( !isset( $translations[ $lang[ 'code' ] ]->element_id ) ): ?>
  4978. <td style="padding:4px;line-height:normal;"><?php echo $lang[ 'display_name' ] ?></td>
  4979. <?php
  4980. $taxonomy = $_GET[ 'taxonomy' ];
  4981. $post_type_q = isset( $_GET[ 'post_type' ] ) ? '&amp;post_type=' . esc_html( $_GET[ 'post_type' ] ) : '';
  4982. $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 );
  4983. ?>
  4984. <td style="padding:4px;line-height:normal;"><a href="<?php echo $add_link ?>"><?php echo __( 'add', 'sitepress' ) ?></a></td>
  4985. <?php endif; ?>
  4986. </tr>
  4987. <?php endforeach; ?>
  4988. </tbody>
  4989. </table>
  4990. <?php endif; ?>
  4991. <?php if ( $translations_found > 0 ): ?>
  4992. <p style="clear:both;margin:5px 0 5px 0">
  4993. <b><?php _e( 'Translations', 'sitepress' ) ?></b>
  4994. (<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
  4995. class="icl_toggle_show_translations" href="#" <?php if (!empty( $this->settings[ 'show_translations_flag' ] )): ?>style="display:none;"<?php endif; ?>><?php _e( 'show', 'sitepress' ) ?></a>)
  4996. <?php wp_nonce_field( 'toggle_show_translations_nonce', '_icl_nonce_tst' ) ?>
  4997. <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;">
  4998. <?php foreach ( $active_languages as $lang ): if ( $selected_language == $lang[ 'code' ] )
  4999. continue; ?>
  5000. <tr>
  5001. <?php if ( isset( $translations[ $lang[ 'code' ] ]->element_id ) ): ?>
  5002. <td style="line-height:normal;"><?php echo $lang[ 'display_name' ] ?></td>
  5003. <?php
  5004. $taxonomy = $_GET[ 'taxonomy' ];
  5005. $post_type_q = isset( $_GET[ 'post_type' ] ) ? '&amp;post_type=' . esc_html( $_GET[ 'post_type' ] ) : '';
  5006. $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 );
  5007. ?>
  5008. <td align="right" width="30%"
  5009. 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>
  5010. <?php endif; ?>
  5011. </tr>
  5012. <?php endforeach; ?>
  5013. </table>
  5014. <?php endif; ?>
  5015. <br clear="all" style="line-height:1px;"/>
  5016. </div>
  5017. <?php
  5018. endif;
  5019. }
  5020. /**
  5021. * @param $name
  5022. *
  5023. * @deprecated deprecated since version 3.1.8
  5024. * @return array|mixed
  5025. */
  5026. function the_category_name_filter( $name ) {
  5027. if ( is_array( $name ) ) {
  5028. foreach ( $name as $k => $v ) {
  5029. $name[ $k ] = $this->the_category_name_filter( $v );
  5030. }
  5031. return $name;
  5032. }
  5033. if ( false === strpos( $name, '@' ) ) {
  5034. return $name;
  5035. }
  5036. if ( false !== strpos( $name, '<a' ) ) {
  5037. $int = preg_match_all( '|<a([^>]+)>([^<]+)</a>|i', $name, $matches );
  5038. if ( $int && count( $matches[ 0 ] ) > 1 ) {
  5039. $originals = $filtered = array();
  5040. foreach ( $matches[ 0 ] as $m ) {
  5041. $originals[ ] = $m;
  5042. $filtered[ ] = $this->the_category_name_filter( $m );
  5043. }
  5044. $name = str_replace( $originals, $filtered, $name );
  5045. } else {
  5046. $name_sh = strip_tags( $name );
  5047. $exp = explode( '@', $name_sh );
  5048. $name = str_replace( $name_sh, trim( $exp[ 0 ] ), $name );
  5049. }
  5050. } else {
  5051. $name = preg_replace( '#(.*) @(.*)#i', '$1', $name );
  5052. }
  5053. return $name;
  5054. }
  5055. /**
  5056. * @param $terms
  5057. *
  5058. * @deprecated deprecated since version 3.1.8
  5059. * @return mixed
  5060. */
  5061. function get_terms_filter( $terms ) {
  5062. if ( is_wp_error( $terms ) ) {
  5063. return $terms;
  5064. }
  5065. foreach ( $terms as $k => $v ) {
  5066. if ( isset( $terms[ $k ]->name ) ) {
  5067. $terms[ $k ]->name = $this->the_category_name_filter( $terms[ $k ]->name );
  5068. }
  5069. }
  5070. return $terms;
  5071. }
  5072. /**
  5073. * @param $terms
  5074. * @param $id
  5075. * @param $taxonomy
  5076. *
  5077. * @deprecated deprecated since version 3.1.8
  5078. * @return mixed
  5079. */
  5080. function get_the_terms_filter( $terms, $id, $taxonomy ) {
  5081. return $terms;
  5082. }
  5083. function create_term( $cat_id, $tt_id )
  5084. {
  5085. global $wpdb, $wp_taxonomies;
  5086. $default_language = $this->get_default_language();
  5087. // case of ajax inline category creation
  5088. // ajax actions
  5089. $ajx_actions = array();
  5090. foreach ( $wp_taxonomies as $ktx => $tx ) {
  5091. $ajx_actions[ ] = 'add-' . $ktx;
  5092. }
  5093. if ( isset( $_POST[ '_ajax_nonce' ] ) && in_array( $_POST[ 'action' ], $ajx_actions ) ) {
  5094. $referer = $_SERVER[ 'HTTP_REFERER' ];
  5095. $url_pieces = parse_url( $referer );
  5096. @parse_str( $url_pieces[ 'query' ], $qvars );
  5097. if ( !empty( $qvars[ 'post' ] ) ) {
  5098. $post_type = $wpdb->get_var( $wpdb->prepare( "SELECT post_type FROM {$wpdb->posts} WHERE ID = %d", $qvars[ 'post' ] ) );
  5099. $term_lang = $qvars[ 'lang' ];
  5100. if($this->is_translated_post_type($post_type)) {
  5101. $lang_details = $this->get_element_language_details( $qvars[ 'post' ], 'post_' . $post_type );
  5102. if(isset($lang_details->language_code)) {
  5103. $term_lang = $lang_details->language_code;
  5104. }
  5105. }
  5106. } else {
  5107. $term_lang = isset( $qvars[ 'lang' ] ) ? $qvars[ 'lang' ] : $this->get_language_cookie();
  5108. }
  5109. }
  5110. $el_type = $wpdb->get_var( "SELECT taxonomy FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id={$tt_id}" );
  5111. if ( !$this->is_translated_taxonomy( $el_type ) ) {
  5112. return;
  5113. };
  5114. $icl_el_type = 'tax_' . $el_type;
  5115. // case of adding a tag via post save
  5116. $post_action = isset( $_POST[ 'action' ] ) ? $_POST[ 'action' ] : false;
  5117. if ( $post_action == 'editpost' && !empty( $_POST[ 'icl_post_language' ] ) ) {
  5118. $term_lang = $_POST[ 'icl_post_language' ];
  5119. } elseif ( $post_action == 'post-quickpress-publish' ) {
  5120. $term_lang = $default_language;
  5121. } elseif ( $post_action == 'inline-save-tax' ) {
  5122. $lang_details = $this->get_element_language_details( $tt_id, $icl_el_type );
  5123. $term_lang = $lang_details->language_code;
  5124. } elseif ( $post_action == 'inline-save' ) {
  5125. $post_type = $wpdb->get_var( "SELECT post_type FROM {$wpdb->posts} WHERE ID=" . $_POST[ 'post_ID' ] );
  5126. $lang_details = $this->get_element_language_details( $_POST[ 'post_ID' ], 'post_' . $post_type );
  5127. $term_lang = $lang_details->language_code;
  5128. }
  5129. // has trid only when it's a translation of another tag
  5130. $trid = isset( $_POST[ 'icl_trid' ] ) && ( isset( $_POST[ 'icl_' . $icl_el_type . '_language' ] ) ) ? $_POST[ 'icl_trid' ] : null;
  5131. // see if we have a "translation of" setting.
  5132. $src_language = false;
  5133. if ( isset( $_POST[ 'icl_translation_of' ] ) && $_POST[ 'icl_translation_of' ] ) {
  5134. $src_term_id = $_POST[ 'icl_translation_of' ];
  5135. $trid = $this->get_element_trid( $src_term_id, $icl_el_type );
  5136. if ( $src_term_id != 'none' && $trid ) {
  5137. $language_details = $this->get_element_language_details( $trid, $icl_el_type );
  5138. if ( empty( $language_details ) || !is_object( $language_details ) || !isset( $language_details->source_language_code ) ) {
  5139. $src_language = null;
  5140. } else {
  5141. $src_language = $language_details->source_language_code;
  5142. }
  5143. } else {
  5144. $trid = null;
  5145. }
  5146. }
  5147. if ( !isset( $term_lang ) ) {
  5148. $term_lang = isset( $_POST[ 'icl_' . $icl_el_type . '_language' ] ) ? $_POST[ 'icl_' . $icl_el_type . '_language' ] : $this->this_lang;
  5149. }
  5150. if ( $post_action == 'inline-save-tax' || $post_action == 'add-' . $el_type ) {
  5151. $trid = $this->get_element_trid( $tt_id, $icl_el_type );
  5152. }
  5153. // set term language if front-end translation creating
  5154. $term_lang = apply_filters( 'wpml_create_term_lang', $term_lang );
  5155. if ( ! $this->is_active_language( $term_lang ) ) {
  5156. $term_lang = $default_language;
  5157. }
  5158. $this->set_element_language_details( $tt_id, $icl_el_type, $trid, $term_lang, $src_language );
  5159. // sync translations parent
  5160. if ( $this->settings[ 'sync_taxonomy_parents' ] && isset( $_POST[ 'parent' ] ) && $term_lang == $default_language ) {
  5161. $parent = intval( $_POST[ 'parent' ] );
  5162. $translations = $this->get_element_translations( $trid, $icl_el_type );
  5163. $taxonomy = isset($_POST[ 'taxonomy' ]) ? $_POST[ 'taxonomy' ] : false;
  5164. foreach ( $translations as $lang => $translation ) {
  5165. if ( $lang != $default_language ) {
  5166. $translated_parent = false;
  5167. //check for translation only if we know the id
  5168. if ( $parent > 0 ) {
  5169. $translated_parent = icl_object_id( $parent, $el_type, false, $lang );
  5170. }
  5171. //update information about parent only if translation exists or we are setting parent to None
  5172. if ( $parent == 0 || $parent == -1 || $translated_parent != $parent ) {
  5173. $wpdb->update( $wpdb->term_taxonomy, array( 'parent' => $translated_parent ), array( 'term_taxonomy_id' => $translation->element_id ) );
  5174. }
  5175. }
  5176. }
  5177. $this->update_terms_relationship_cache( $parent, $taxonomy );
  5178. }
  5179. }
  5180. function get_language_for_term( $term_id, $el_type )
  5181. {
  5182. global $wpdb;
  5183. $ttid = $wpdb->get_var( "SELECT term_taxonomy_id FROM {$wpdb->prefix}term_taxonomy WHERE term_id = {$term_id} AND taxonomy = '{$el_type}' " );
  5184. if ( $ttid ) {
  5185. $el_type = 'tax_' . $el_type;
  5186. return $wpdb->get_var( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_id = {$ttid} AND element_type = '{$el_type}'" );
  5187. } else {
  5188. return $this->get_default_language();
  5189. }
  5190. }
  5191. function terms_language_filter()
  5192. {
  5193. global $wpdb;
  5194. $taxonomy = isset( $_GET[ 'taxonomy' ] ) ? $_GET[ 'taxonomy' ] : 'post_tag';
  5195. $icl_element_type = 'tax_' . $taxonomy;
  5196. $active_languages = $this->get_active_languages();
  5197. $current_language=$this->get_current_language();
  5198. $default_language=$this->get_default_language();
  5199. $res_query = "
  5200. SELECT language_code, COUNT(tm.term_id) AS c FROM {$wpdb->prefix}icl_translations t
  5201. JOIN {$wpdb->term_taxonomy} tt ON t.element_id = tt.term_taxonomy_id
  5202. JOIN {$wpdb->terms} tm ON tt.term_id = tm.term_id
  5203. JOIN {$wpdb->prefix}icl_languages l ON t.language_code = l.code
  5204. WHERE t.element_type=%s AND tt.taxonomy=%s AND l.active=1
  5205. GROUP BY language_code
  5206. ";
  5207. $res_query_prepared = $wpdb->prepare($res_query, array($icl_element_type, $taxonomy) );
  5208. $res = $wpdb->get_results( $res_query_prepared );
  5209. $languages = array( 'all' => 0 );
  5210. foreach ( $res as $r ) {
  5211. $languages[ $r->language_code ] = $r->c;
  5212. $languages[ 'all' ] += $r->c;
  5213. }
  5214. $active_languages[ ] = array( 'code' => 'all', 'display_name' => __( 'All languages', 'sitepress' ) );
  5215. $languages_links = array();
  5216. foreach ( $active_languages as $lang ) {
  5217. if ( $lang[ 'code' ] == $this->this_lang ) {
  5218. $px = '<strong>';
  5219. $sx = ' (' . @intval( $languages[ $lang[ 'code' ] ] ) . ')<\/strong>';
  5220. /*
  5221. }elseif(!isset($langs[$lang['code']])){
  5222. $px = '<span>';
  5223. $sx = '<\/span>';
  5224. */
  5225. } else {
  5226. $px = '<a href="?taxonomy=' . $taxonomy . '&amp;lang=' . $lang[ 'code' ];
  5227. $px .= isset( $_GET[ 'post_type' ] ) ? '&amp;post_type=' . $_GET[ 'post_type' ] : '';
  5228. $px .= '">';
  5229. $sx = '<\/a> (' . @intval( $languages[ $lang[ 'code' ] ] ) . ')';
  5230. }
  5231. $languages_links[ ] = $px . $lang[ 'display_name' ] . $sx;
  5232. }
  5233. $all_languages_links = join( ' | ', $languages_links );
  5234. ?>
  5235. <script type="text/javascript">
  5236. jQuery('table.widefat').before('<span id="icl_subsubsub"><?php echo $all_languages_links ?><\/span>');
  5237. <?php // the search form, add language ?>
  5238. <?php if($current_language != $default_language): ?>
  5239. jQuery('.search-form').append('<input type="hidden" name="lang" value="<?php echo $current_language ?>" />');
  5240. <?php endif; ?>
  5241. </script>
  5242. <?php
  5243. }
  5244. function get_terms_args_filter( $args )
  5245. {
  5246. // Unique cache domain for each language.
  5247. if ( isset( $args[ 'cache_domain' ] ) ) {
  5248. $args[ 'cache_domain' ] .= '_' . $this->get_current_language();
  5249. }
  5250. // special case for when term hierarchy is cached in wp_options
  5251. $debug_backtrace = $this->get_backtrace( 5 ); //Limit to first 5 stack frames, since 4 is the highest index we use
  5252. if ( isset( $debug_backtrace[ 4 ] ) && $debug_backtrace[ 4 ][ 'function' ] == '_get_term_hierarchy' ) {
  5253. $args[ '_icl_show_all_langs' ] = true;
  5254. }
  5255. return $args;
  5256. }
  5257. function exclude_other_terms( $exclusions, $args )
  5258. {
  5259. if ( !version_compare( $GLOBALS[ 'wp_version' ], '3.1', '>=' ) ) {
  5260. $default_language = $this->get_default_language();
  5261. // special case for when term hierarchy is cached in wp_options
  5262. if ( isset( $args[ '_icl_show_all_langs' ] ) && $args[ '_icl_show_all_langs' ] )
  5263. return $exclusions;
  5264. // get_terms doesn't seem to have a filter that can be used efficiently in order to filter the terms by language
  5265. // in addition the taxonomy name is not being passed to this filter we're using 'list_terms_exclusions'
  5266. // getting the taxonomy name from debug_backtrace
  5267. global $wpdb, $pagenow;
  5268. $taxonomy = false;
  5269. if ( isset( $_GET[ 'taxonomy' ] ) ) {
  5270. $taxonomy = $_GET[ 'taxonomy' ];
  5271. } elseif ( isset( $args[ 'taxonomy' ] ) ) {
  5272. $taxonomy = $args[ 'taxonomy' ];
  5273. } elseif ( isset( $_POST[ 'action' ] ) && $_POST[ 'action' ] == 'get-tagcloud' ) {
  5274. $taxonomy = $_POST[ 'tax' ];
  5275. } else {
  5276. if ( in_array( $pagenow, array( 'post-new.php', 'post.php', 'edit.php' ) ) ) {
  5277. $debug_backtrace = $this->get_backtrace( 4, false, true ); //Limit to first 4 stack frames, since 3 is the highest index we use
  5278. if ( isset( $debug_backtrace[ 3 ][ 'args' ][ 0 ] ) ) {
  5279. $taxonomy = $debug_backtrace[ 3 ][ 'args' ][ 0 ];
  5280. } else {
  5281. $taxonomy = 'post_tag';
  5282. }
  5283. }
  5284. }
  5285. if ( ! $taxonomy || ! $this->is_translated_taxonomy( $taxonomy ) ) {
  5286. return $exclusions;
  5287. }
  5288. $icl_element_type = 'tax_' . $taxonomy;
  5289. if ( isset( $_GET[ 'lang' ] ) && $_GET[ 'lang' ] == 'all' ) {
  5290. return $exclusions;
  5291. }
  5292. if ( isset( $_GET[ 'tag_ID' ] ) && $_GET[ 'tag_ID' ] ) {
  5293. $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 );
  5294. $this_lang = $element_lang_details->language_code;
  5295. } elseif ( $this->this_lang != $default_language ) {
  5296. $this_lang = $this->get_current_language();
  5297. } elseif ( isset( $_GET[ 'post' ] ) ) {
  5298. $icl_post_type = isset( $_GET[ 'post_type' ] ) ? 'post_' . $_GET[ 'post_type' ] : 'post_' . $wpdb->get_var( $wpdb->prepare( "SELECT post_type FROM {$wpdb->posts} WHERE ID = %d", $_GET[ 'post' ] ) );
  5299. $element_lang_details = $this->get_element_language_details( $_GET[ 'post' ], $icl_post_type );
  5300. $this_lang = $element_lang_details ? $element_lang_details->language_code : $default_language;
  5301. } elseif ( isset( $_POST[ 'action' ] ) && ( $_POST[ 'action' ] == 'get-tagcloud' || $_POST[ 'action' ] == 'menu-quick-search' ) ) {
  5302. if ( ! isset( $_SERVER[ 'HTTP_REFERER' ] ) ) {
  5303. $this_lang = $default_language;
  5304. } else {
  5305. $urlparts = parse_url( $_SERVER[ 'HTTP_REFERER' ] );
  5306. @parse_str( $urlparts[ 'query' ], $qvars );
  5307. $this_lang = isset( $qvars[ 'lang' ] ) ? $qvars[ 'lang' ] : $default_language;
  5308. }
  5309. } else {
  5310. $this_lang = $default_language;
  5311. }
  5312. $exclude = $wpdb->get_col( "
  5313. SELECT tt.term_taxonomy_id FROM {$wpdb->term_taxonomy} tt
  5314. LEFT JOIN {$wpdb->terms} tm ON tt.term_id = tm.term_id
  5315. LEFT JOIN {$wpdb->prefix}icl_translations t ON (tt.term_taxonomy_id = t.element_id OR t.element_id IS NULL)
  5316. WHERE tt.taxonomy='{$taxonomy}' AND t.element_type='{$icl_element_type}' AND t.language_code <> '{$this_lang}'
  5317. " );
  5318. $exclude[ ] = 0;
  5319. $exclusions .= ' AND tt.term_taxonomy_id NOT IN (' . join( ',', $exclude ) . ')';
  5320. }
  5321. return $exclusions;
  5322. }
  5323. function terms_clauses( $clauses, $taxonomies, $args )
  5324. {
  5325. if ( version_compare( $GLOBALS[ 'wp_version' ], '3.1', '>=' ) ) {
  5326. global $wpdb;
  5327. // special case for when term hierarchy is cached in wp_options
  5328. $debug_backtrace = $this->get_backtrace( 6 ); //Limit to first 5 stack frames, since 4 is the highest index we use
  5329. if ( isset( $debug_backtrace[ 4 ] ) && $debug_backtrace[ 4 ][ 'function' ] == '_get_term_hierarchy' ) {
  5330. return $clauses;
  5331. }
  5332. //Todo: to remove: this is for debug purposes and only temporary
  5333. if(defined('WP_DEBUG') && WP_DEBUG===true) {
  5334. $wp_upload_dir = wp_upload_dir();
  5335. $icl_log_file = $wp_upload_dir['basedir'] . "/wpml.debug.txt";
  5336. foreach($debug_backtrace as $index => $data) {
  5337. if($index!=4 && $debug_backtrace[ $index ][ 'function' ] == '_get_term_hierarchy') {
  5338. file_put_contents($icl_log_file, '_get_term_hierarchy found on position ' . $index . PHP_EOL, FILE_APPEND);
  5339. file_put_contents($icl_log_file, 'Stack: ' . print_r($debug_backtrace, true) . PHP_EOL, FILE_APPEND);
  5340. }
  5341. }
  5342. }
  5343. $int = preg_match( '#tt\.taxonomy IN \(([^\)]+)\)#', $clauses[ 'where' ], $matches );
  5344. $left_join = '';
  5345. $icl_taxonomies = array();
  5346. if ( $int ) {
  5347. $exp = explode( ',', $matches[ 1 ] );
  5348. foreach ( $exp as $v ) {
  5349. $tax = trim( $v, ' \'' );
  5350. if ( $this->is_translated_taxonomy( $tax ) ) {
  5351. $icl_taxonomies[ ] = 'tax_' . $tax;
  5352. } else {
  5353. $left_join = ' LEFT';
  5354. }
  5355. }
  5356. } else {
  5357. // taxonomy type not found
  5358. return $clauses;
  5359. }
  5360. if ( empty( $icl_taxonomies ) )
  5361. return $clauses;
  5362. $icl_taxonomies = "'" . join( "','", $icl_taxonomies ) . "'";
  5363. $lang = $this->get_current_language();
  5364. if ( $lang == 'all' ) {
  5365. $left_join = ' LEFT';
  5366. $where_lang = '';
  5367. } else {
  5368. $where_lang = " AND icl_t.language_code = '{$lang}'";
  5369. }
  5370. $clauses[ 'join' ] .= "{$left_join} JOIN {$wpdb->prefix}icl_translations icl_t ON icl_t.element_id = tt.term_taxonomy_id";
  5371. $clauses[ 'where' ] .= "{$where_lang} AND icl_t.element_type IN({$icl_taxonomies})";
  5372. //echo '<pre>' . print_r($clauses) . '</pre>';
  5373. }
  5374. return $clauses;
  5375. }
  5376. function set_wp_query()
  5377. {
  5378. global $wp_query;
  5379. $this->wp_query = $wp_query;
  5380. }
  5381. private function home_url_in_language_switcher($debug_backtrace) {
  5382. $level_7 = isset($debug_backtrace[7]);
  5383. $in_footer = ($debug_backtrace[7]['function']=='language_selector_footer');
  5384. $in_dropdown_widget = ( $debug_backtrace[7]['function']=='language_selector' );
  5385. $in_list_widget = ( $debug_backtrace[7]['function']=='icl_get_languages' );
  5386. $in_nav_menu = ( $debug_backtrace[7]['function']=='wp_nav_menu_items_filter' );
  5387. return ( $level_7 && ( $in_footer || $in_dropdown_widget || $in_list_widget || $in_nav_menu ) );
  5388. }
  5389. // filter for WP home_url function
  5390. function home_url( $url, $path, $orig_scheme, $blog_id )
  5391. {
  5392. $debug_backtrace = $this->get_backtrace( 8 ); //Limit to first 8 stack frames, since 7 is the highest index we use
  5393. // exception for get_page_num_link and language_negotiation_type = 3
  5394. if ( $this->settings[ 'language_negotiation_type' ] == 3 ) {
  5395. if ( !empty( $debug_backtrace[ 6 ] ) && $debug_backtrace[ 6 ][ 'function' ] == 'get_pagenum_link' )
  5396. return $url;
  5397. }
  5398. $convert_url = false;
  5399. // only apply this in some specific cases (1)
  5400. if(isset($debug_backtrace[5]) && $debug_backtrace[5]['function']=='get_post_type_archive_link') {
  5401. $convert_url = true;
  5402. if($this->home_url_in_language_switcher($debug_backtrace)) {
  5403. $convert_url = false;
  5404. }
  5405. }
  5406. remove_filter( 'home_url', array( $this, 'home_url' ), 1 );
  5407. // only apply this in some specific cases (2)
  5408. if(!$convert_url && ( did_action( 'template_redirect' ) && rtrim( $url, '/' ) == rtrim( get_home_url(), '/' ) ) || $path == '/') {
  5409. $convert_url = true;
  5410. }
  5411. if ( $convert_url ) {
  5412. $url = $this->convert_url( $url );
  5413. }
  5414. add_filter( 'home_url', array( $this, 'home_url' ), 1, 4 );
  5415. return $url;
  5416. }
  5417. /**
  5418. * Converts WP generated url to language specific based on plugin settings
  5419. *
  5420. * @param string $url
  5421. * @param null|string $code (if null, fallback to detaulf language for root page, or current language in all other cases)
  5422. *
  5423. * @return bool|string
  5424. */
  5425. function convert_url( $url, $code = null ) {
  5426. global $wpdb;
  5427. if(!$url) return false;
  5428. $default_language = $this->get_default_language();
  5429. $current_language = $this->get_current_language();
  5430. $language_negotiation_type = $this->settings[ 'language_negotiation_type' ];
  5431. if ( is_null( $code ) && $language_negotiation_type == '2' && isset( $this->settings[ 'language_domains' ] ) ) {
  5432. foreach ( $this->settings[ 'language_domains' ] as $lang => $domain ) {
  5433. $domain = preg_replace( '/^https?\:\/\//', '', $domain );
  5434. $domain_data = explode('/', $domain);
  5435. $domain = $domain_data[0];
  5436. if ( $domain == $this->get_server_host_name() ) {
  5437. $code = $lang;
  5438. }
  5439. }
  5440. if ( is_null( $code ) ) {
  5441. $code = $default_language;
  5442. }
  5443. }
  5444. if ( is_null( $code ) ) {
  5445. $code = $this->this_lang;
  5446. }
  5447. $cache_key_args = array( $url, $code, $current_language );
  5448. $cache_key = md5(json_encode( $cache_key_args ));
  5449. $cache_group = 'convert_url';
  5450. $cache_found = false;
  5451. $new_url = wp_cache_get($cache_key, $cache_group, false, $cache_found);
  5452. if(!$cache_found) {
  5453. $new_url = $url;
  5454. if ( $code && ( $code != $default_language || in_array( $language_negotiation_type, array( 1, 2 ) ) ) ) {
  5455. remove_filter( 'home_url', array( $this, 'home_url' ), 1 );
  5456. $absolute_home_url = preg_replace( '@\?lang=' . $code . '@i', '', get_home_url() );
  5457. add_filter( 'home_url', array( $this, 'home_url' ), 1, 4 );
  5458. switch ( $language_negotiation_type ) {
  5459. case '1':
  5460. if ( 0 === strpos( $new_url, 'https://' ) ) {
  5461. $absolute_home_url = preg_replace( '#^http://#', 'https://', $absolute_home_url );
  5462. }
  5463. if ( $absolute_home_url == $new_url ) {
  5464. $new_url .= '/';
  5465. }
  5466. if ( false === strpos( $new_url, $absolute_home_url . '/' . $code . '/' ) ) {
  5467. //we have to check if we have a language slug in the current url
  5468. $current_lang_slug = "";
  5469. if ( false !== strpos( $new_url, $absolute_home_url . '/' . $current_language . '/' ) ) {
  5470. $current_lang_slug = '/' . $current_language;
  5471. }
  5472. if ( ! $this->settings[ 'urls' ][ 'directory_for_default_language' ] && $code == $default_language ) {
  5473. //in case the default language has no directory we have to treat it differently
  5474. $code = '';
  5475. } else {
  5476. $code = '/' . $code;
  5477. }
  5478. $new_url = str_replace( $absolute_home_url . $current_lang_slug, $absolute_home_url . $code, $new_url );
  5479. }
  5480. break;
  5481. case '2':
  5482. $is_https = strpos( $new_url, 'https://' ) === 0;
  5483. if ( $is_https ) {
  5484. preg_replace( '#^http://#', 'https://', $new_url );
  5485. } // normalize protocol
  5486. $this->settings[ 'language_domains' ][ $default_language ] = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'");
  5487. $new_url = str_replace( $absolute_home_url, $this->settings[ 'language_domains' ][ $code ], $new_url );
  5488. if ( $is_https ) {
  5489. preg_replace( '#^http://#', 'https://', $new_url );
  5490. } // normalize protocol (rev)
  5491. break;
  5492. case '3':
  5493. default:
  5494. // remove any previous value.
  5495. if ( strpos( $new_url, '?lang=' . $code . '&' ) !== false ) {
  5496. $new_url = str_replace( '?lang=' . $code . '&', '', $new_url );
  5497. } elseif ( strpos( $new_url, '?lang=' . $code . '/' ) !== false ) {
  5498. $new_url = str_replace( '?lang=' . $code . '/', '', $new_url );
  5499. } elseif ( strpos( $new_url, '?lang=' . $code ) !== false ) {
  5500. $new_url = str_replace( '?lang=' . $code, '', $new_url );
  5501. } elseif ( strpos( $new_url, '&lang=' . $code . '/' ) !== false ) {
  5502. $new_url = str_replace( '&lang=' . $code . '/', '', $new_url );
  5503. } elseif ( strpos( $new_url, '&lang=' . $code ) !== false ) {
  5504. $new_url = str_replace( '&lang=' . $code, '', $new_url );
  5505. }
  5506. if ( false === strpos( $new_url, '?' ) ) {
  5507. $new_url_glue = '?';
  5508. } else {
  5509. $new_url_glue = '&';
  5510. }
  5511. $new_url .= $new_url_glue . 'lang=' . $code;
  5512. }
  5513. }
  5514. wp_cache_set($cache_key, $new_url, $cache_group);
  5515. }
  5516. return $new_url;
  5517. }
  5518. function language_url( $code = null )
  5519. {
  5520. global $wpdb;
  5521. if ( is_null( $code ) ) {
  5522. $code = $this->this_lang;
  5523. }
  5524. $abs_home = false;
  5525. if ( $code == $this->get_default_language() && $this->settings[ 'language_negotiation_type' ] == 2 ) {
  5526. $option_value = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'siteurl'");
  5527. if($option_value){
  5528. $abs_home = $option_value;
  5529. }
  5530. } else {
  5531. remove_filter( 'home_url', array( $this, 'home_url' ), 1 );
  5532. $abs_home = get_home_url();
  5533. add_filter( 'home_url', array( $this, 'home_url' ), 1, 4 );
  5534. }
  5535. if ( $this->settings[ 'language_negotiation_type' ] == 1 || $this->settings[ 'language_negotiation_type' ] == 2 ) {
  5536. $url = trailingslashit( $this->convert_url( $abs_home, $code ) );
  5537. } else {
  5538. $url = $this->convert_url( $abs_home, $code );
  5539. }
  5540. return $url;
  5541. }
  5542. function permalink_filter( $p, $pid )
  5543. {
  5544. global $wp_query;
  5545. if ( is_object( $pid ) ) {
  5546. $post_type = $pid->post_type;
  5547. $pid = $pid->ID;
  5548. } else {
  5549. $_post = get_post( $pid );
  5550. $post_type = $_post->post_type;
  5551. }
  5552. if ( !$this->is_translated_post_type( $post_type ) )
  5553. return $p;
  5554. if ( $pid == (int)get_option( 'page_on_front' ) ) {
  5555. return $p;
  5556. }
  5557. $default_language = $this->get_default_language();
  5558. $element_lang_details = $this->get_element_language_details( $pid, 'post_' . $post_type );
  5559. $use_directory = $this->settings[ 'language_negotiation_type' ] == 1 && $this->settings[ 'urls' ][ 'directory_for_default_language' ];
  5560. if ( !empty( $element_lang_details ) && $element_lang_details->language_code && ( $default_language != $element_lang_details->language_code || $use_directory ) ) {
  5561. $p = $this->convert_url( $p, $element_lang_details->language_code );
  5562. } elseif ( isset( $_POST[ 'action' ] ) && $_POST[ 'action' ] == 'sample-permalink' ) { // check whether this is an autosaved draft
  5563. if ( !isset( $_SERVER[ 'HTTP_REFERER' ] ) ) {
  5564. $p = $this->convert_url( $p, $default_language );
  5565. } else {
  5566. $exp = explode( '?', $_SERVER[ "HTTP_REFERER" ] );
  5567. if ( isset( $exp[ 1 ] ) )
  5568. parse_str( $exp[ 1 ], $args );
  5569. if ( isset( $args[ 'lang' ] ) && $default_language != $args[ 'lang' ] ) {
  5570. $p = $this->convert_url( $p, $args[ 'lang' ] );
  5571. }
  5572. }
  5573. }
  5574. if ( isset( $wp_query ) && is_feed() ) {
  5575. $p = str_replace( "&lang=", "&#038;lang=", $p );
  5576. }
  5577. return $p;
  5578. }
  5579. function category_permalink_filter( $p, $cat_id )
  5580. {
  5581. global $wpdb;
  5582. if ( isset( $this->icl_term_taxonomy_cache ) ) {
  5583. $term_cat_id = $this->icl_term_taxonomy_cache->get( 'category_' . $cat_id );
  5584. } else {
  5585. $term_cat_id = null;
  5586. }
  5587. if ( !$term_cat_id ) {
  5588. $term_cat_id = $wpdb->get_var( "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id={$cat_id} AND taxonomy='category'" );
  5589. if ( isset( $this->icl_term_taxonomy_cache ) ) {
  5590. $this->icl_term_taxonomy_cache->set( 'category_' . $cat_id, $term_cat_id );
  5591. }
  5592. }
  5593. $cat_id = $term_cat_id;
  5594. $element_lang_details = $this->get_element_language_details( $cat_id, 'tax_category' );
  5595. $use_directory = $this->settings[ 'language_negotiation_type' ] == 1 && $this->settings[ 'urls' ][ 'directory_for_default_language' ];
  5596. if ( $this->get_default_language() != $element_lang_details->language_code || $use_directory ) {
  5597. $p = $this->convert_url( $p, $element_lang_details->language_code );
  5598. }
  5599. return $p;
  5600. }
  5601. function post_type_archive_link_filter( $link, $post_type )
  5602. {
  5603. if ( isset( $this->settings[ 'custom_posts_sync_option' ][ $post_type ] ) && $this->settings[ 'custom_posts_sync_option' ][ $post_type ] ) {
  5604. $link = $this->convert_url( $link );
  5605. $link = $this->adjust_cpt_in_url( $link, $post_type );
  5606. }
  5607. return $link;
  5608. }
  5609. function adjust_cpt_in_url($link, $post_type) {
  5610. global $sitepress_settings;
  5611. if ( function_exists('icl_t') && isset($sitepress_settings['st']['strings_language']) && $this->get_current_language() != $sitepress_settings['st']['strings_language']) {
  5612. if ( isset($this->settings['posts_slug_translation']['types'][$post_type]) && $this->settings['posts_slug_translation']['types'][$post_type] ) {
  5613. $post_type_object = get_post_type_object($post_type);
  5614. if (isset($post_type_object->rewrite)) {
  5615. $slug = $post_type_object->rewrite['slug'];
  5616. } else {
  5617. $slug = $post_type_object->name;
  5618. }
  5619. $translated_slug = icl_t('WordPress', 'URL slug: ' . $slug, $slug);
  5620. if (is_string($translated_slug)) {
  5621. $link = preg_replace("/". preg_quote($slug, "/") ."/", $translated_slug, $link, 1);
  5622. }
  5623. }
  5624. }
  5625. return $link;
  5626. }
  5627. function tax_permalink_filter( $p, $tag )
  5628. {
  5629. global $wpdb;
  5630. if ( is_object( $tag ) ) {
  5631. $tag_id = $tag->term_taxonomy_id;
  5632. $taxonomy = $tag->taxonomy;
  5633. } else {
  5634. $taxonomy = 'post_tag';
  5635. if ( empty( $tag_id ) ) {
  5636. $tag_id = $wpdb->get_var( "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id={$tag} AND taxonomy='{$taxonomy}'" );
  5637. if ( isset( $this->icl_term_taxonomy_cache ) ) {
  5638. $this->icl_term_taxonomy_cache->set( $taxonomy . '_' . $tag, $tag_id );
  5639. }
  5640. }
  5641. }
  5642. $cached_permalink_key = $tag_id . '.' . $taxonomy;
  5643. $cached_permalink = wp_cache_get($cached_permalink_key, 'icl_tax_permalink_filter');
  5644. if($cached_permalink) {
  5645. return $cached_permalink;
  5646. }
  5647. $element_lang_details = $this->get_element_language_details( $tag_id, 'tax_' . $taxonomy );
  5648. $use_directory = $this->settings[ 'language_negotiation_type' ] == 1 && $this->settings[ 'urls' ][ 'directory_for_default_language' ];
  5649. if ( !empty( $element_lang_details ) && ( $this->get_default_language() != $element_lang_details->language_code || $use_directory ) ) {
  5650. $p = $this->convert_url( $p, $element_lang_details->language_code );
  5651. }
  5652. wp_cache_set($cached_permalink_key, $p, 'icl_tax_permalink_filter');
  5653. return $p;
  5654. }
  5655. function get_comment_link_filter( $link )
  5656. {
  5657. // decode html characters since they are already encoded in the template for some reason
  5658. $link = html_entity_decode( $link );
  5659. return $link;
  5660. }
  5661. function attachment_link_filter( $link, $id )
  5662. {
  5663. //FIXME: check if we really need to call SitePress::convert_url in all other cases
  5664. if($this->get_setting( 'language_negotiation_type' ) == 2) {
  5665. $convert_url = $this->permalink_filter( $link, $id );
  5666. } else {
  5667. $convert_url = $this->convert_url( $link );
  5668. }
  5669. return $convert_url;
  5670. }
  5671. function get_ls_languages( $template_args = array() )
  5672. {
  5673. //Returns false if is admin and settings are corrupted
  5674. if(is_admin() && !SitePress::check_settings_integrity()) return false;
  5675. /** @var $wp_query WP_Query */
  5676. global $sitepress, $wpdb, $wp_query, $w_this_lang;
  5677. $current_language = $this->get_current_language();
  5678. $default_language = $this->get_default_language();
  5679. $cache_key_args = $template_args ? array_filter($template_args) : array('default');
  5680. $cache_key_args[] = $current_language;
  5681. $cache_key_args[] = $default_language;
  5682. $cache_key_args = array_filter($cache_key_args);
  5683. $cache_key = md5(json_encode($cache_key_args));
  5684. $cache_group = 'ls_languages';
  5685. $found = false;
  5686. $ls_languages = wp_cache_get($cache_key, $cache_group, $found);
  5687. if($found) return $ls_languages;
  5688. if ( is_null( $this->wp_query ) )
  5689. $this->set_wp_query();
  5690. // use original wp_query for this
  5691. // backup current $wp_query
  5692. if ( !isset( $wp_query ) )
  5693. return $this->get_active_languages();
  5694. $_wp_query_back = clone $wp_query;
  5695. unset( $wp_query );
  5696. global $wp_query; // make it global again after unset
  5697. $wp_query = clone $this->wp_query;
  5698. $w_active_languages = $this->get_active_languages();
  5699. $this_lang = $this->this_lang;
  5700. if ( $this_lang == 'all' ) {
  5701. $w_this_lang = array(
  5702. 'code' => 'all', 'english_name' => 'All languages', 'display_name' => __( 'All languages', 'sitepress' )
  5703. );
  5704. } else {
  5705. $w_this_lang = $this->get_language_details( $this_lang );
  5706. }
  5707. if ( isset( $template_args[ 'skip_missing' ] ) ) {
  5708. //override default setting
  5709. $icl_lso_link_empty = !$template_args[ 'skip_missing' ];
  5710. } else {
  5711. $icl_lso_link_empty = $this->settings[ 'icl_lso_link_empty' ];
  5712. }
  5713. // 1. Determine translations
  5714. if ( is_category() ) {
  5715. $skip_empty = false;
  5716. $term_taxonomy_id_prepared = $wpdb->prepare( "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", array( get_query_var( 'cat' ), 'category' ) );
  5717. $term_taxonomy_id = $wpdb->get_var( $term_taxonomy_id_prepared );
  5718. $trid = $sitepress->get_element_trid( $term_taxonomy_id, 'tax_category' );
  5719. $translations = $this->get_element_translations( $trid, 'tax_category', $skip_empty );
  5720. } elseif ( is_tag() ) {
  5721. $skip_empty = false;
  5722. $term_taxonomy_id_prepared = $wpdb->prepare( "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", array( get_query_var( 'tag_id' ), 'post_tag' ) );
  5723. $term_taxonomy_id = $wpdb->get_var( $term_taxonomy_id_prepared );
  5724. $trid = $sitepress->get_element_trid( $term_taxonomy_id, 'tax_post_tag' );
  5725. $translations = $this->get_element_translations( $trid, 'tax_post_tag', $skip_empty );
  5726. } elseif ( is_tax() ) {
  5727. $skip_empty = false;
  5728. $term_taxonomy_id_prepared = $wpdb->prepare( "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", array( $wp_query->get_queried_object_id(), get_query_var( 'taxonomy' ) ) );
  5729. $term_taxonomy_id = $wpdb->get_var( $term_taxonomy_id_prepared );
  5730. if ( $this->is_translated_taxonomy( get_query_var( 'taxonomy' ) ) ) {
  5731. $trid = $this->get_element_trid( $term_taxonomy_id, 'tax_' . get_query_var( 'taxonomy' ) );
  5732. $translations = $this->get_element_translations( $trid, 'tax_' . get_query_var( 'taxonomy' ), $skip_empty );
  5733. } else {
  5734. $translations[ $this->get_current_language() ] = (object)array(
  5735. 'translation_id' => 0,
  5736. 'language_code' => $this->get_default_language(),
  5737. 'original' => 1,
  5738. 'name' => get_query_var( 'taxonomy' ),
  5739. 'term_id' => $wp_query->get_queried_object_id()
  5740. );
  5741. }
  5742. } elseif ( is_archive() ) {
  5743. $translations = array();
  5744. } elseif ( is_attachment() ) { // Exception for attachments. Not translated.
  5745. $trid = $sitepress->get_element_trid($wp_query->get_queried_object_id(), 'post_attachment' );
  5746. $translations = $this->get_element_translations( $trid, 'post_attachment' );
  5747. } elseif (is_page() || ('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' )) ) ) ) {
  5748. $trid = $sitepress->get_element_trid($wp_query->get_queried_object_id(), 'post_page' );
  5749. $translations = $this->get_element_translations( $trid, 'post_page' );
  5750. } elseif ( is_singular() && !empty( $wp_query->posts ) ) {
  5751. $trid = $sitepress->get_element_trid($this->wp_query->post->ID, 'post_' . $wp_query->posts[ 0 ]->post_type);
  5752. $translations = $this->get_element_translations( $trid, 'post_' . $wp_query->posts[ 0 ]->post_type );
  5753. } else {
  5754. $wp_query->is_singular = false;
  5755. $wp_query->is_archive = false;
  5756. $wp_query->is_category = false;
  5757. $wp_query->is_404 = true;
  5758. }
  5759. // 2. determine url
  5760. foreach ( $w_active_languages as $k => $lang ) {
  5761. $skip_lang = false;
  5762. if ( is_singular() || ( !empty( $this->wp_query->queried_object_id ) && $this->wp_query->queried_object_id == get_option( 'page_for_posts' ) ) ) {
  5763. $this_lang_tmp = $this->this_lang;
  5764. $this->this_lang = $lang[ 'code' ];
  5765. $lang_page_on_front = get_option( 'page_on_front' );
  5766. $lang_page_for_posts = get_option( 'page_for_posts' );
  5767. if($lang_page_on_front && $lang[ 'code' ] != $default_language) {
  5768. $lang_page_on_front = icl_object_id($lang_page_on_front, 'page', false, $lang[ 'code' ]);
  5769. }
  5770. if($lang_page_for_posts && $lang[ 'code' ] != $default_language) {
  5771. $lang_page_for_posts = icl_object_id($lang_page_for_posts, 'page', false, $lang[ 'code' ]);
  5772. }
  5773. if ( 'page' == get_option( 'show_on_front' ) && !empty( $translations[ $lang[ 'code' ] ] ) && $translations[ $lang[ 'code' ] ]->element_id == $lang_page_on_front ) {
  5774. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] );
  5775. } 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 ) {
  5776. if ( $lang_page_for_posts ) {
  5777. $lang[ 'translated_url' ] = get_permalink( $lang_page_for_posts );
  5778. } else {
  5779. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] );
  5780. }
  5781. } else {
  5782. if ( !empty( $translations[ $lang[ 'code' ] ] ) && isset( $translations[ $lang[ 'code' ] ]->post_title ) ) {
  5783. $lang[ 'translated_url' ] = get_permalink( $translations[ $lang[ 'code' ] ]->element_id );
  5784. $lang[ 'missing' ] = 0;
  5785. } else {
  5786. if ( $icl_lso_link_empty ) {
  5787. if ( !empty( $template_args[ 'link_empty_to' ] ) ) {
  5788. $lang[ 'translated_url' ] = str_replace( '{%lang}', $lang[ 'code' ], $template_args[ 'link_empty_to' ] );
  5789. } else {
  5790. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] );
  5791. }
  5792. } else {
  5793. $skip_lang = true;
  5794. }
  5795. $lang[ 'missing' ] = 1;
  5796. }
  5797. }
  5798. $this->this_lang = $this_lang_tmp;
  5799. } elseif ( is_category() ) {
  5800. if ( isset( $translations[ $lang[ 'code' ] ] ) ) {
  5801. global $icl_adjust_id_url_filter_off; // force the category_link_adjust_id to not modify this
  5802. $icl_adjust_id_url_filter_off = true;
  5803. $lang[ 'translated_url' ] = get_category_link( $translations[ $lang[ 'code' ] ]->term_id );
  5804. $icl_adjust_id_url_filter_off = false; // restore default bahavior
  5805. $lang[ 'missing' ] = 0;
  5806. } else {
  5807. if ( $icl_lso_link_empty ) {
  5808. if ( !empty( $template_args[ 'link_empty_to' ] ) ) {
  5809. $lang[ 'translated_url' ] = str_replace( '{%lang}', $lang[ 'code' ], $template_args[ 'link_empty_to' ] );
  5810. } else {
  5811. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] );
  5812. }
  5813. } else {
  5814. // dont skip the currrent language
  5815. if ( $current_language != $lang[ 'code' ] ) {
  5816. $skip_lang = true;
  5817. }
  5818. }
  5819. $lang[ 'missing' ] = 1;
  5820. }
  5821. } elseif ( is_tax() ) {
  5822. if ( isset( $translations[ $lang[ 'code' ] ] ) ) {
  5823. global $icl_adjust_id_url_filter_off; // force the category_link_adjust_id to not modify this
  5824. $icl_adjust_id_url_filter_off = true;
  5825. $lang[ 'translated_url' ] = get_term_link( (int)$translations[ $lang[ 'code' ] ]->term_id, get_query_var( 'taxonomy' ) );
  5826. $icl_adjust_id_url_filter_off = false; // restore default bahavior
  5827. $lang[ 'missing' ] = 0;
  5828. } else {
  5829. if ( $icl_lso_link_empty ) {
  5830. if ( !empty( $template_args[ 'link_empty_to' ] ) ) {
  5831. $lang[ 'translated_url' ] = str_replace( '{%lang}', $lang[ 'code' ], $template_args[ 'link_empty_to' ] );
  5832. } else {
  5833. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] );
  5834. }
  5835. } else {
  5836. // dont skip the currrent language
  5837. if ( $current_language != $lang[ 'code' ] ) {
  5838. $skip_lang = true;
  5839. }
  5840. }
  5841. $lang[ 'missing' ] = 1;
  5842. }
  5843. } elseif ( is_tag() ) {
  5844. if ( isset( $translations[ $lang[ 'code' ] ] ) ) {
  5845. global $icl_adjust_id_url_filter_off; // force the category_link_adjust_id to not modify this
  5846. $icl_adjust_id_url_filter_off = true;
  5847. $lang[ 'translated_url' ] = get_tag_link( $translations[ $lang[ 'code' ] ]->term_id );
  5848. $icl_adjust_id_url_filter_off = false; // restore default bahavior
  5849. $lang[ 'missing' ] = 0;
  5850. } else {
  5851. if ( $icl_lso_link_empty ) {
  5852. if ( !empty( $template_args[ 'link_empty_to' ] ) ) {
  5853. $lang[ 'translated_url' ] = str_replace( '{%lang}', $lang[ 'code' ], $template_args[ 'link_empty_to' ] );
  5854. } else {
  5855. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] );
  5856. }
  5857. } else {
  5858. // dont skip the currrent language
  5859. if ( $current_language != $lang[ 'code' ] ) {
  5860. $skip_lang = true;
  5861. }
  5862. }
  5863. $lang[ 'missing' ] = 1;
  5864. }
  5865. } elseif ( is_author() ) {
  5866. global $authordata, $wp_query;
  5867. if ( empty( $authordata ) ) {
  5868. $authordata = get_userdata( get_query_var( 'author' ) );
  5869. }
  5870. $post_type = get_query_var( 'post_type' ) ? get_query_var( 'post_type' ) : 'post';
  5871. if ( $wpdb->get_var( "SELECT COUNT(p.ID) FROM {$wpdb->posts} p
  5872. JOIN {$wpdb->prefix}icl_translations t ON p.ID=t.element_id AND t.element_type = 'post_{$post_type}'
  5873. WHERE p.post_author='{$authordata->ID}' AND post_type='{$post_type}' AND post_status='publish' AND language_code='{$lang['code']}'" )
  5874. ) {
  5875. remove_filter( 'home_url', array( $this, 'home_url' ), 1, 4 );
  5876. remove_filter( 'author_link', array( $this, 'author_link' ) );
  5877. $author_url = get_author_posts_url( $authordata->ID );
  5878. add_filter( 'home_url', array( $this, 'home_url' ), 1, 4 );
  5879. add_filter( 'author_link', array( $this, 'author_link' ) );
  5880. $lang[ 'translated_url' ] = $this->convert_url( $author_url, $lang[ 'code' ] );
  5881. $lang[ 'missing' ] = 0;
  5882. } else {
  5883. if ( $icl_lso_link_empty ) {
  5884. if ( !empty( $template_args[ 'link_empty_to' ] ) ) {
  5885. $lang[ 'translated_url' ] = str_replace( '{%lang}', $lang[ 'code' ], $template_args[ 'link_empty_to' ] );
  5886. } else {
  5887. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] );
  5888. }
  5889. } else {
  5890. // dont skip the currrent language
  5891. if ( $current_language != $lang[ 'code' ] ) {
  5892. $skip_lang = true;
  5893. }
  5894. }
  5895. $lang[ 'missing' ] = 1;
  5896. }
  5897. } elseif ( is_archive() && !is_tag() ) {
  5898. global $icl_archive_url_filter_off;
  5899. $icl_archive_url_filter_off = true;
  5900. if ( $this->wp_query->is_year ) {
  5901. if ( isset( $this->wp_query->query_vars[ 'm' ] ) && !$this->wp_query->query_vars[ 'year' ] ) {
  5902. $this->wp_query->query_vars[ 'year' ] = substr( $this->wp_query->query_vars[ 'm' ], 0, 4 );
  5903. }
  5904. $lang[ 'translated_url' ] = $this->archive_url( get_year_link( $this->wp_query->query_vars[ 'year' ] ), $lang[ 'code' ] );
  5905. } elseif ( $this->wp_query->is_month ) {
  5906. if ( isset( $this->wp_query->query_vars[ 'm' ] ) && !$this->wp_query->query_vars[ 'year' ] ) {
  5907. $this->wp_query->query_vars[ 'year' ] = substr( $this->wp_query->query_vars[ 'm' ], 0, 4 );
  5908. $this->wp_query->query_vars[ 'monthnum' ] = substr( $this->wp_query->query_vars[ 'm' ], 4, 2 );
  5909. } else {
  5910. if ( $icl_lso_link_empty ) {
  5911. if ( !empty( $template_args[ 'link_empty_to' ] ) ) {
  5912. $lang[ 'translated_url' ] = str_replace( '{%lang}', $lang[ 'code' ], $template_args[ 'link_empty_to' ] );
  5913. } else {
  5914. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] );
  5915. }
  5916. }
  5917. $lang[ 'missing' ] = 1;
  5918. }
  5919. $lang[ 'translated_url' ] = $this->archive_url( get_month_link( $this->wp_query->query_vars[ 'year' ], $this->wp_query->query_vars[ 'monthnum' ] ), $lang[ 'code' ] );
  5920. } elseif ( $this->wp_query->is_day ) {
  5921. if ( isset( $this->wp_query->query_vars[ 'm' ] ) && !$this->wp_query->query_vars[ 'year' ] ) {
  5922. $this->wp_query->query_vars[ 'year' ] = substr( $this->wp_query->query_vars[ 'm' ], 0, 4 );
  5923. $this->wp_query->query_vars[ 'monthnum' ] = substr( $this->wp_query->query_vars[ 'm' ], 4, 2 );
  5924. $this->wp_query->query_vars[ 'day' ] = substr( $this->wp_query->query_vars[ 'm' ], 6, 2 );
  5925. gmdate( 'Y', current_time( 'timestamp' ) ); //force wp_timezone_override_offset to be called
  5926. }
  5927. $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' ] );
  5928. } else if ( isset( $this->wp_query->query_vars[ 'post_type' ] ) ) {
  5929. do_action( '_icl_before_archive_url', $this->wp_query->query_vars[ 'post_type' ], $lang[ 'code' ] );
  5930. if ( $this->is_translated_post_type( $this->wp_query->query_vars[ 'post_type' ] ) && function_exists( 'get_post_type_archive_link' ) ) {
  5931. remove_filter( 'post_type_archive_link', array( $this, 'post_type_archive_link_filter' ), 10 );
  5932. $lang[ 'translated_url' ] = $this->convert_url( get_post_type_archive_link( $this->wp_query->query_vars[ 'post_type' ] ), $lang[ 'code' ] );
  5933. } else {
  5934. if($k != $this->get_default_language()){
  5935. $skip_lang = true;
  5936. unset( $w_active_languages[ $k ] );
  5937. }
  5938. }
  5939. do_action( '_icl_after_archive_url', $this->wp_query->query_vars[ 'post_type' ], $lang[ 'code' ] );
  5940. }
  5941. add_filter( 'post_type_archive_link', array( $this, 'post_type_archive_link_filter' ), 10, 2 );
  5942. $icl_archive_url_filter_off = false;
  5943. } elseif ( is_search() ) {
  5944. $url_glue = strpos( $this->language_url( $lang[ 'code' ] ), '?' ) === false ? '?' : '&';
  5945. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] ) . $url_glue . 's=' . urlencode( $wp_query->query[ 's' ] );
  5946. } else {
  5947. global $icl_language_switcher_preview;
  5948. if ( $icl_lso_link_empty || is_home() || is_404() || ( 'page' == get_option( 'show_on_front' ) && ( $this->wp_query->queried_object_id == get_option( 'page_on_front' ) || $this->wp_query->queried_object_id == get_option( 'page_for_posts' ) ) ) || $icl_language_switcher_preview || $this->is_root_page() ) {
  5949. $lang[ 'translated_url' ] = $this->language_url( $lang[ 'code' ] );
  5950. $skip_lang = false;
  5951. } else {
  5952. $skip_lang = true;
  5953. unset( $w_active_languages[ $k ] );
  5954. }
  5955. }
  5956. if ( !$skip_lang ) {
  5957. $w_active_languages[ $k ] = $lang;
  5958. } else {
  5959. unset( $w_active_languages[ $k ] );
  5960. }
  5961. }
  5962. // 3.
  5963. foreach ( $w_active_languages as $k => $v ) {
  5964. $lang_code = $w_active_languages[ $k ][ 'language_code' ] = $w_active_languages[ $k ][ 'code' ];
  5965. unset( $w_active_languages[ $k ][ 'code' ] );
  5966. $native_name = $this->get_display_language_name( $lang_code, $lang_code );
  5967. if ( !$native_name )
  5968. $native_name = $w_active_languages[ $k ][ 'english_name' ];
  5969. $w_active_languages[ $k ][ 'native_name' ] = $native_name;
  5970. $translated_name = $this->get_display_language_name( $lang_code, $current_language );
  5971. if ( !$translated_name )
  5972. $translated_name = $w_active_languages[ $k ][ 'english_name' ];
  5973. $w_active_languages[ $k ][ 'translated_name' ] = $translated_name;
  5974. unset( $w_active_languages[ $k ][ 'display_name' ] );
  5975. unset( $w_active_languages[ $k ][ 'english_name' ] );
  5976. if ( isset( $w_active_languages[ $k ][ 'translated_url' ] ) ) {
  5977. $w_active_languages[ $k ][ 'url' ] = $w_active_languages[ $k ][ 'translated_url' ];
  5978. unset( $w_active_languages[ $k ][ 'translated_url' ] );
  5979. } else {
  5980. $w_active_languages[ $k ][ 'url' ] = $this->language_url( $k );
  5981. }
  5982. $flag = $this->get_flag( $lang_code );
  5983. if ( $flag->from_template ) {
  5984. $wp_upload_dir = wp_upload_dir();
  5985. $flag_url = $wp_upload_dir[ 'baseurl' ] . '/flags/' . $flag->flag;
  5986. } else {
  5987. $flag_url = ICL_PLUGIN_URL . '/res/flags/' . $flag->flag;
  5988. }
  5989. $w_active_languages[ $k ][ 'country_flag_url' ] = $flag_url;
  5990. $w_active_languages[ $k ][ 'active' ] = $current_language == $lang_code ? '1' : 0;;
  5991. }
  5992. // 4. pass GET parameters
  5993. $parameters_copied = apply_filters( 'icl_lang_sel_copy_parameters', array_map( 'trim', explode( ',', $this->settings[ 'icl_lang_sel_copy_parameters' ] ) ) );
  5994. if ( $parameters_copied ) {
  5995. foreach ( $_GET as $k => $v ) {
  5996. if ( in_array( $k, $parameters_copied ) ) {
  5997. $gets_passed[ $k ] = $v;
  5998. }
  5999. }
  6000. }
  6001. if ( !empty( $gets_passed ) ) {
  6002. $gets_passed = http_build_query( $gets_passed );
  6003. foreach ( $w_active_languages as $code => $al ) {
  6004. if ( empty( $al[ 'missing' ] ) ) {
  6005. $glue = false !== strpos( $w_active_languages[ $code ][ 'url' ], '?' ) ? '&' : '?';
  6006. $w_active_languages[ $code ][ 'url' ] .= $glue . $gets_passed;
  6007. }
  6008. }
  6009. }
  6010. // restore current $wp_query
  6011. unset( $wp_query );
  6012. global $wp_query; // make it global again after unset
  6013. $wp_query = clone $_wp_query_back;
  6014. unset( $_wp_query_back );
  6015. $w_active_languages = apply_filters( 'icl_ls_languages', $w_active_languages );
  6016. $w_active_languages = $this->sort_ls_languages( $w_active_languages, $template_args );
  6017. // Change the url, in case languages in subdomains are set.
  6018. if ( $this->settings[ 'language_negotiation_type' ] == 2 ) {
  6019. foreach ( $w_active_languages as $lang => $element ) {
  6020. $w_active_languages[ $lang ][ 'url' ] = $this->convert_url( $element[ 'url' ], $lang );
  6021. }
  6022. }
  6023. wp_reset_query();
  6024. wp_cache_set($cache_key, $w_active_languages, $cache_group);
  6025. return $w_active_languages;
  6026. }
  6027. function sort_ls_languages( $w_active_languages, $template_args )
  6028. {
  6029. // sort languages according to parameters
  6030. $orderby = isset( $template_args[ 'orderby' ] ) ? $template_args[ 'orderby' ] : 'custom';
  6031. $order = isset( $template_args[ 'order' ] ) ? $template_args[ 'order' ] : 'asc';
  6032. $comp = $order == 'asc' ? '>' : '<';
  6033. switch ( $orderby ) {
  6034. case 'id':
  6035. uasort( $w_active_languages, create_function( '$a,$b', 'return $a[\'id\'] ' . $comp . ' $b[\'id\'];' ) );
  6036. break;
  6037. case 'code':
  6038. ksort( $w_active_languages );
  6039. if ( $order == 'desc' ) {
  6040. $w_active_languages = array_reverse( $w_active_languages );
  6041. }
  6042. break;
  6043. case 'name':
  6044. uasort( $w_active_languages, create_function( '$a,$b', 'return $a[\'translated_name\'] ' . $comp . ' $b[\'translated_name\'];' ) );
  6045. break;
  6046. case 'custom':
  6047. default:
  6048. $w_active_languages = $this->order_languages( $w_active_languages );
  6049. }
  6050. return $w_active_languages;
  6051. }
  6052. function get_display_language_name( $lang_code, $display_code )
  6053. {
  6054. global $wpdb;
  6055. if ( isset( $this->icl_language_name_cache ) ) {
  6056. $translated_name = $this->icl_language_name_cache->get( $lang_code . $display_code );
  6057. } else {
  6058. $translated_name = null;
  6059. }
  6060. if ( !$translated_name ) {
  6061. $display_code = $display_code == 'all' ? $this->get_admin_language() : $display_code;
  6062. $translated_name = $wpdb->get_var( "SELECT name FROM {$wpdb->prefix}icl_languages_translations WHERE language_code='{$lang_code}' AND display_language_code='{$display_code}'" );
  6063. if ( isset( $this->icl_language_name_cache ) ) {
  6064. $this->icl_language_name_cache->set( $lang_code . $display_code, $translated_name );
  6065. }
  6066. }
  6067. return $translated_name;
  6068. }
  6069. function get_flag( $lang_code )
  6070. {
  6071. global $wpdb;
  6072. if ( isset( $this->icl_flag_cache ) ) {
  6073. $flag = $this->icl_flag_cache->get( $lang_code );
  6074. } else {
  6075. $flag = null;
  6076. }
  6077. if ( !$flag ) {
  6078. $flag = $wpdb->get_row( "SELECT flag, from_template FROM {$wpdb->prefix}icl_flags WHERE lang_code='{$lang_code}'" );
  6079. if ( isset( $this->icl_flag_cache ) ) {
  6080. $this->icl_flag_cache->set( $lang_code, $flag );
  6081. }
  6082. }
  6083. return $flag;
  6084. }
  6085. function get_flag_url( $code )
  6086. {
  6087. $flag = $this->get_flag( $code );
  6088. if ( $flag->from_template ) {
  6089. $wp_upload_dir = wp_upload_dir();
  6090. $flag_url = $wp_upload_dir[ 'baseurl' ] . '/flags/' . $flag->flag;
  6091. } else {
  6092. $flag_url = ICL_PLUGIN_URL . '/res/flags/' . $flag->flag;
  6093. }
  6094. return $flag_url;
  6095. }
  6096. function set_up_language_selector()
  6097. {
  6098. // language selector
  6099. // load js and style for js language selector
  6100. if (isset($this->settings[ 'icl_lang_sel_type' ]) && $this->settings[ 'icl_lang_sel_type' ] == 'dropdown' && ( !is_admin() || ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == ICL_PLUGIN_FOLDER . '/menu/languages.php' ) ) ) {
  6101. if ( $this->settings[ 'icl_lang_sel_stype' ] == 'mobile-auto' ) {
  6102. include ICL_PLUGIN_PATH . '/lib/mobile-detect.php';
  6103. $WPML_Mobile_Detect = new WPML_Mobile_Detect;
  6104. $this->is_mobile = $WPML_Mobile_Detect->isMobile();
  6105. $this->is_tablet = $WPML_Mobile_Detect->isTablet();
  6106. }
  6107. if ( ( $this->settings[ 'icl_lang_sel_stype' ] == 'mobile-auto' && ( !empty( $this->is_mobile ) || !empty( $this->is_tablet ) ) ) || $this->settings[ 'icl_lang_sel_stype' ] == 'mobile'
  6108. ) {
  6109. if(!defined('ICL_DONT_LOAD_LANGUAGES_JS') || !ICL_DONT_LOAD_LANGUAGES_JS) {
  6110. wp_enqueue_script( 'language-selector', ICL_PLUGIN_URL . '/res/js/language-selector.js', false, ICL_SITEPRESS_VERSION, true );
  6111. }
  6112. if(!defined('ICL_DONT_LOAD_LANGUAGE_SELECTOR_CSS') || !ICL_DONT_LOAD_LANGUAGE_SELECTOR_CSS) {
  6113. wp_enqueue_style( 'language-selector', ICL_PLUGIN_URL . '/res/css/language-selector-click.css', ICL_SITEPRESS_VERSION );
  6114. }
  6115. }
  6116. }
  6117. }
  6118. function get_desktop_language_selector() {
  6119. $active_languages = $this->get_ls_languages();
  6120. if ( $active_languages ) {
  6121. /**
  6122. * @var $main_language bool|string
  6123. * @used_by menu/language-selector.php
  6124. */
  6125. foreach ( $active_languages as $k => $al ) {
  6126. if ( $al[ 'active' ] == 1 ) {
  6127. unset( $active_languages[ $k ] );
  6128. break;
  6129. }
  6130. }
  6131. } else {
  6132. return '';
  6133. }
  6134. global $w_this_lang;
  6135. global $icl_language_switcher_preview;
  6136. if($w_this_lang['code']=='all'){
  6137. $main_language['native_name'] = __('All languages', 'sitepress');
  6138. $main_language['translated_name'] = $main_language['native_name'];
  6139. $main_language['language_code'] = 'all';
  6140. }
  6141. if(empty($main_language)){
  6142. $main_language['native_name'] = $w_this_lang['display_name'];
  6143. $main_language['translated_name'] = $w_this_lang['display_name'];
  6144. $main_language['language_code'] = $w_this_lang['code'];
  6145. }
  6146. $style_display_none_icl_lang_sel_type = $this->settings['icl_lang_sel_type'] == 'list' ? ' style="display:none;"' : '';
  6147. $class_icl_rtl = $this->is_rtl() ? 'class="icl_rtl"' : '';
  6148. $language_selector = '<div id="lang_sel" '.$style_display_none_icl_lang_sel_type.' '.$class_icl_rtl.' >
  6149. <ul>
  6150. <li><a href="#" class="lang_sel_sel icl-'.$w_this_lang['code'].'">';
  6151. if ( $this->settings[ 'icl_lso_flags' ] || $icl_language_switcher_preview ) {
  6152. $flag = $this->get_flag($w_this_lang['code']);
  6153. if ( isset( $flag->from_template ) && $flag->from_template && isset( $flag->flag ) ) {
  6154. $wp_upload_dir = wp_upload_dir();
  6155. $main_language['country_flag_url'] = $wp_upload_dir['baseurl'] . '/flags/' . $flag->flag;
  6156. }else{
  6157. if(isset($flag->flag)){
  6158. $main_language['country_flag_url'] = ICL_PLUGIN_URL . '/res/flags/'.$flag->flag;
  6159. } else {
  6160. $main_language['country_flag_url'] = ICL_PLUGIN_URL . '/res/img/icon16.png';
  6161. }
  6162. }
  6163. $language_selector .= '<img ' . ( !$this->settings['icl_lso_flags'] ? 'style="display:none"' : '' )
  6164. . ' class="iclflag" '
  6165. . 'src="'.$main_language['country_flag_url'].'" '
  6166. . 'alt="'.$main_language['language_code'].'" '
  6167. . 'title="'. ($this->settings['icl_lso_display_lang'] ? esc_attr($main_language['translated_name']) : esc_attr($main_language['native_name']) ) .'" />
  6168. &nbsp;';
  6169. }
  6170. if($icl_language_switcher_preview){
  6171. $lang_native = $main_language['native_name'];
  6172. if($this->settings['icl_lso_native_lang']){
  6173. $lang_native_hidden = false;
  6174. }else{
  6175. $lang_native_hidden = true;
  6176. }
  6177. $lang_translated = $main_language['translated_name'];
  6178. if($this->settings['icl_lso_display_lang']){
  6179. $lang_translated_hidden = false;
  6180. }else{
  6181. $lang_translated_hidden = true;
  6182. }
  6183. }else{
  6184. if($this->settings['icl_lso_native_lang']){
  6185. $lang_native = $main_language['native_name'];
  6186. }else{
  6187. $lang_native = false;
  6188. }
  6189. if($this->settings['icl_lso_display_lang']){
  6190. $lang_translated = $main_language['translated_name'];
  6191. }else{
  6192. $lang_translated = false;
  6193. }
  6194. $lang_native_hidden = false;
  6195. $lang_translated_hidden = false;
  6196. }
  6197. $language_selector .= icl_disp_language($lang_native, $lang_translated, $lang_native_hidden, $lang_translated_hidden);
  6198. if(!isset($ie_ver) || $ie_ver > 6):
  6199. $language_selector .= '</a> ';
  6200. endif;
  6201. if(!empty($active_languages)) {
  6202. if(isset($ie_ver) && $ie_ver <= 6):
  6203. $language_selector .= '<table><tr><td>';
  6204. endif;
  6205. $language_selector .= '<ul>';
  6206. $active_languages_ordered = $this->order_languages($active_languages);
  6207. foreach($active_languages_ordered as $lang) {
  6208. $language_selector .= '<li class="icl-'.$lang['language_code'].'">
  6209. <a href="'.apply_filters('WPML_filter_link', $lang['url'], $lang).'">';
  6210. if( $this->settings['icl_lso_flags'] || $icl_language_switcher_preview):
  6211. $language_selector .= '<img '. ( !$this->settings['icl_lso_flags'] ? 'style="display:none"' : '' )
  6212. . ' class="iclflag" '
  6213. . 'src="'.$lang['country_flag_url'].'" '
  6214. . 'alt="'.$lang['language_code'].'" '
  6215. . 'title="'. ($this->settings['icl_lso_display_lang'] ? esc_attr($lang['translated_name']) : esc_attr($lang['native_name']) ) .'" />&nbsp;';
  6216. endif;
  6217. if($icl_language_switcher_preview){
  6218. $lang_native = $lang['native_name'];
  6219. if($this->settings['icl_lso_native_lang']){
  6220. $lang_native_hidden = false;
  6221. }else{
  6222. $lang_native_hidden = true;
  6223. }
  6224. $lang_translated = $lang['translated_name'];
  6225. if($this->settings['icl_lso_display_lang']){
  6226. $lang_translated_hidden = false;
  6227. }else{
  6228. $lang_translated_hidden = true;
  6229. }
  6230. }else{
  6231. if($this->settings['icl_lso_native_lang']){
  6232. $lang_native = $lang['native_name'];
  6233. }else{
  6234. $lang_native = false;
  6235. }
  6236. if($this->settings['icl_lso_display_lang']){
  6237. $lang_translated = $lang['translated_name'];
  6238. }else{
  6239. $lang_translated = false;
  6240. }
  6241. }
  6242. $language_selector .= icl_disp_language($lang_native, $lang_translated, $lang_native_hidden, $lang_translated_hidden);
  6243. $language_selector .= '</a>
  6244. </li>';
  6245. }
  6246. $language_selector .= '</ul>';
  6247. if(isset($ie_ver) && $ie_ver <= 6):
  6248. $language_selector .= '</td></tr></table></a>';
  6249. endif;
  6250. }
  6251. $language_selector .= '</li>
  6252. </ul>
  6253. </div>';
  6254. return $language_selector;
  6255. }
  6256. function get_mobile_language_selector() {
  6257. $languages = $this->get_ls_languages();
  6258. foreach($languages as $code => $language){
  6259. if($code == $this->get_current_language()){
  6260. $current_language = $language;
  6261. unset($languages[$code]);
  6262. break;
  6263. }
  6264. }
  6265. $user_agent = $_SERVER['HTTP_USER_AGENT'];
  6266. if(preg_match('#MSIE ([0-9]+)\.[0-9]#',$user_agent,$matches)){
  6267. $ie_ver = $matches[1];
  6268. }
  6269. $language_selector_mobile = '<div id="lang_sel_click" '
  6270. . 'onclick="wpml_language_selector_click.toggle();" '
  6271. . 'class="lang_sel_click'.($this->is_rtl() ? 'icl_rtl' : '').'" >'
  6272. . '<ul>'
  6273. . '<li>';
  6274. $language_selector_mobile .= '<a href="javascript:;" class="lang_sel_sel icl-'.$current_language['language_code'].'">';
  6275. if( $this->settings['icl_lso_flags'] ):
  6276. $language_selector_mobile .= '<img class="iclflag" '
  6277. . 'src="'.$current_language['country_flag_url'].'" '
  6278. . 'alt="'.$current_language['language_code'].'" '
  6279. . 'title="'. ($this->settings['icl_lso_display_lang'] ? esc_attr($current_language['translated_name']) : esc_attr($current_language['native_name']) ) .'" />';
  6280. endif;
  6281. if($this->settings['icl_lso_display_lang'] || $this->settings['icl_lso_native_lang']){
  6282. $language_selector_mobile .= $current_language['native_name'];
  6283. }
  6284. if(!isset($ie_ver) || $ie_ver > 6):
  6285. $language_selector_mobile .= '</a>';
  6286. endif;
  6287. if(isset($ie_ver) && $ie_ver <= 6):
  6288. $language_selector_mobile .= '<table><tr><td>';
  6289. endif;
  6290. $language_selector_mobile .= '<ul>';
  6291. foreach($languages as $code => $language) {
  6292. $language_selector_mobile .= '<li class="icl-'.$language['language_code'].'">'
  6293. . '<a rel="alternate" href="'.apply_filters('WPML_filter_link', $language['url'], $language).'">';
  6294. if( $this->settings['icl_lso_flags'] ):
  6295. $language_selector_mobile .= '<img class="iclflag" '
  6296. . 'src="'.$language['country_flag_url'].'" '
  6297. . 'alt="'.$language['language_code'].'" '
  6298. . 'title="'.($this->settings['icl_lso_display_lang'] ? esc_attr($language['translated_name']) : esc_attr($language['native_name']) ).'" />&nbsp;';
  6299. endif;
  6300. if($this->settings['icl_lso_display_lang'] && $this->settings['icl_lso_native_lang']){
  6301. $language_name = '<span class="icl_lang_sel_native">' . $language['native_name'] .'</span>
  6302. <span class="icl_lang_sel_translated">(' . $language['translated_name'] . ')</span>';
  6303. }elseif($this->settings['icl_lso_display_lang']){
  6304. $language_name = '<span class="icl_lang_sel_translated">' . $language['translated_name'] . '</span>';
  6305. }elseif($this->settings['icl_lso_native_lang']){
  6306. $language_name = '<span class="icl_lang_sel_native">' . $language['native_name'] .'</span>';
  6307. }else{
  6308. $language_name = '';
  6309. }
  6310. $language_selector_mobile .= $language_name;
  6311. $language_selector_mobile .= '</a>'
  6312. . '</li>';
  6313. }
  6314. $language_selector_mobile .= '</ul>';
  6315. if(isset($ie_ver) && $ie_ver <= 6):
  6316. $language_selector_mobile .= '</td></tr></table></a>';
  6317. endif;
  6318. $language_selector_mobile .= '</li>'
  6319. . '</ul>'
  6320. . '</div>';
  6321. return $language_selector_mobile;
  6322. }
  6323. function get_language_selector() {
  6324. // Mobile or auto
  6325. $is_mobile = $this->settings[ 'icl_lang_sel_stype' ] == 'mobile' || ( $this->settings[ 'icl_lang_sel_stype' ] == 'mobile-auto' && (!empty( $this->is_tablet ) || !empty( $this->is_mobile ) ) );
  6326. if ( $this->settings[ 'icl_lang_sel_type' ] == 'dropdown' && ( $is_mobile )
  6327. ) {
  6328. return $this->get_mobile_language_selector();;
  6329. } else {
  6330. global $icl_language_switcher_preview;
  6331. if ( $this->settings[ 'icl_lang_sel_type' ] == 'list' || $icl_language_switcher_preview ) {
  6332. global $icl_language_switcher;
  6333. $icl_language_switcher->widget_list();
  6334. if ( ! $icl_language_switcher_preview ) {
  6335. return '';
  6336. }
  6337. }
  6338. return $this->get_desktop_language_selector();
  6339. }
  6340. return '';
  6341. }
  6342. function language_selector()
  6343. {
  6344. echo $this->get_language_selector();
  6345. }
  6346. function have_icl_translator( $source, $target )
  6347. {
  6348. // returns true if we have ICL translators for the language pair
  6349. if ( isset( $this->settings[ 'icl_lang_status' ] ) ) {
  6350. foreach ( $this->settings[ 'icl_lang_status' ] as $lang ) {
  6351. if ( $lang[ 'from' ] == $source && $lang[ 'to' ] == $target ) {
  6352. return $lang[ 'have_translators' ];
  6353. }
  6354. }
  6355. }
  6356. return false;
  6357. }
  6358. public function add_extra_debug_info( $extra_debug ) {
  6359. $extra_debug[ 'WMPL' ] = $this->get_settings();
  6360. return $extra_debug;
  6361. }
  6362. function get_default_categories()
  6363. {
  6364. $default_categories_all = $this->settings[ 'default_categories' ];
  6365. $active_languages_codes = false;
  6366. foreach ( $this->active_languages as $l ) {
  6367. $active_languages_codes[ ] = $l[ 'code' ];
  6368. }
  6369. $default_categories = array();
  6370. if ( is_array( $default_categories_all ) && is_array( $active_languages_codes ) ) {
  6371. foreach ( $default_categories_all as $c => $v ) {
  6372. if ( in_array( $c, $active_languages_codes ) ) {
  6373. $default_categories[ $c ] = $v;
  6374. }
  6375. }
  6376. }
  6377. return $default_categories;
  6378. }
  6379. function set_default_categories( $def_cat )
  6380. {
  6381. $this->settings[ 'default_categories' ] = $def_cat;
  6382. $this->save_settings();
  6383. }
  6384. function pre_option_default_category( $setting )
  6385. {
  6386. global $wpdb;
  6387. if ( isset( $_POST[ 'icl_post_language' ] ) && $_POST[ 'icl_post_language' ] || ( isset( $_GET[ 'lang' ] ) && $_GET[ 'lang' ] != 'all' ) ) {
  6388. $lang = isset( $_POST[ 'icl_post_language' ] ) && $_POST[ 'icl_post_language' ] ? $_POST[ 'icl_post_language' ] : $_GET[ 'lang' ];
  6389. $ttid = @intval( $this->settings[ 'default_categories' ][ $lang ] );
  6390. return $tid = $wpdb->get_var( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id={$ttid} AND taxonomy='category'" );
  6391. }
  6392. return false;
  6393. }
  6394. function update_option_default_category( $oldvalue, $new_value )
  6395. {
  6396. global $wpdb;
  6397. $new_value = $wpdb->get_var( $wpdb->prepare( "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE taxonomy='category' AND term_id=%d", $new_value ) );
  6398. $translations = $this->get_element_translations( $this->get_element_trid( $new_value, 'tax_category' ) );
  6399. if ( !empty( $translations ) ) {
  6400. foreach ( $translations as $t ) {
  6401. $icl_settings[ 'default_categories' ][ $t->language_code ] = $t->element_id;
  6402. }
  6403. if ( isset( $icl_settings ) ) {
  6404. $this->save_settings( $icl_settings );
  6405. }
  6406. }
  6407. }
  6408. function get_term_adjust_id( $term ) {
  6409. //TODO: To remove? I couldn't find a single place where this is used, since $term->term_id == $translated_id. Testing always returning the passed value.
  6410. // comment from Konrad: don't remove this as it is still used by nav menus
  6411. global $icl_adjust_id_url_filter_off;
  6412. if ( $icl_adjust_id_url_filter_off ) {
  6413. return $term;
  6414. } // special cases when we need the category in a different language
  6415. // exception: don't filter when called from get_permalink. When category parents are determined
  6416. $debug_backtrace = $this->get_backtrace( 7 ); //Limit to first 7 stack frames, since 6 is the highest index we use
  6417. if ( isset( $debug_backtrace[ 5 ][ 'function' ] ) &&
  6418. $debug_backtrace[ 5 ][ 'function' ] == 'get_category_parents' ||
  6419. isset( $debug_backtrace[ 6 ][ 'function' ] ) &&
  6420. $debug_backtrace[ 6 ][ 'function' ] == 'get_permalink' ||
  6421. isset( $debug_backtrace[ 4 ][ 'function' ] ) &&
  6422. $debug_backtrace[ 4 ][ 'function' ] == 'get_permalink' // WP 3.5
  6423. ) {
  6424. return $term;
  6425. }
  6426. $translated_id = icl_object_id( $term->term_id, $term->taxonomy, true );
  6427. $cache_key = $term->taxonomy . ':' . $translated_id;
  6428. $cache_group = 'icl_get_term_adjust_id';
  6429. $cache_found = false;
  6430. $cached_term = wp_cache_get( $cache_key, $cache_group, false, $cache_found );
  6431. if ( $cache_found ) {
  6432. return $cached_term;
  6433. }
  6434. if ( $translated_id != $term->term_id ) {
  6435. //$translated_id = $wpdb->get_var("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id='{$translated_id}'");
  6436. remove_filter( 'get_term', array( $this, 'get_term_adjust_id' ), 1 );
  6437. $t_term = get_term( $translated_id, $term->taxonomy );
  6438. if ( !is_wp_error( $t_term ) ) {
  6439. $term = $t_term;
  6440. }
  6441. add_filter( 'get_term', array( $this, 'get_term_adjust_id' ), 1, 1 );
  6442. }
  6443. wp_cache_set( $cache_key, $term, $cache_group );
  6444. return $term;
  6445. }
  6446. function set_term_translation( $original_term, $translation_id, $type, $lang, $original_lang )
  6447. {
  6448. global $wpdb;
  6449. if ( $original_term ) {
  6450. $trid = $this->get_element_trid( $original_term->term_taxonomy_id, 'tax_' . $type );
  6451. $this->set_element_language_details( $translation_id, 'tax_' . $type, $trid, $lang, $original_lang );
  6452. } else {
  6453. // Original has been deleled.
  6454. // we need to set the language of the new term.
  6455. $wpdb->update( $wpdb->prefix . 'icl_translations', array( 'language_code' => $lang ), array( 'element_type' => 'tax_' . $type, 'element_id' => $translation_id ) );
  6456. }
  6457. }
  6458. function wp_list_pages_adjust_ids( $out, $args )
  6459. {
  6460. static $__run_once = false; // only run for calls that have 'include' as an argument. ant only run once.
  6461. if ( $args[ 'include' ] && !$__run_once && $this->get_current_language() != $this->get_default_language() ) {
  6462. $__run_once = true;
  6463. $include = array_map( 'trim', explode( ',', $args[ 'include' ] ) );
  6464. $tr_include = array();
  6465. foreach ( $include as $i ) {
  6466. $t = icl_object_id( $i, 'page', true );
  6467. if ( $t ) {
  6468. $tr_include[ ] = $t;
  6469. }
  6470. }
  6471. $args[ 'include' ] = join( ',', $tr_include );
  6472. $out = wp_list_pages( $args );
  6473. }
  6474. return $out;
  6475. }
  6476. function get_terms_adjust_ids( $terms, $taxonomies, $args )
  6477. {
  6478. static $__run_once = false; // only run for calls that have 'include' as an argument. ant only run once.
  6479. if ( $args[ 'include' ] && !$__run_once && $this->get_current_language() != $this->get_default_language() ) {
  6480. $__run_once = true;
  6481. if ( is_array( $args[ 'include' ] ) ) {
  6482. $include = $args[ 'include' ];
  6483. } else {
  6484. $include = array_map( 'trim', explode( ',', $args[ 'include' ] ) );
  6485. }
  6486. $tr_include = array();
  6487. foreach ( $include as $i ) {
  6488. $t = icl_object_id( $i, $taxonomies[ 0 ], true );
  6489. if ( $t ) {
  6490. $tr_include[ ] = $t;
  6491. }
  6492. }
  6493. $args[ 'include' ] = join( ',', $tr_include );
  6494. $terms = get_terms( $taxonomies, $args );
  6495. }
  6496. return $terms;
  6497. }
  6498. function get_pages_adjust_ids( $pages, $args )
  6499. {
  6500. if ($pages && $this->get_current_language() != $this->get_default_language() ) {
  6501. $cache_key_args = md5(json_encode(wp_list_pluck($pages, 'ID')));
  6502. $cache_key_args .= ":";
  6503. $cache_key_args .= md5(json_encode($args));
  6504. $cache_key = $cache_key_args;
  6505. $cache_group = 'get_pages_adjust_ids';
  6506. $found = false;
  6507. $cached_result = wp_cache_get($cache_key, $cache_group, false, $found);
  6508. if(!$found) {
  6509. $args_updated = false;
  6510. if ( $args[ 'include' ] ) {
  6511. $include = array_map( 'trim', explode( ',', $args[ 'include' ] ) );
  6512. $tr_include = array();
  6513. foreach ( $include as $i ) {
  6514. $t = icl_object_id( $i, 'page', true );
  6515. if ( $t ) {
  6516. $tr_include[ ] = $t;
  6517. }
  6518. }
  6519. $args[ 'include' ] = join( ',', $tr_include );
  6520. $args_updated = true;
  6521. }
  6522. if ( $args[ 'exclude' ] ) {
  6523. $exclude = array_map( 'trim', explode( ',', $args[ 'exclude' ] ) );
  6524. $tr_exclude = array();
  6525. foreach ( $exclude as $i ) {
  6526. $t = icl_object_id( $i, 'page', true );
  6527. if ( $t ) {
  6528. $tr_exclude[ ] = $t;
  6529. }
  6530. }
  6531. $args[ 'exclude' ] = join( ',', $tr_exclude );
  6532. $args_updated = true;
  6533. }
  6534. if ( $args[ 'child_of' ] ) {
  6535. $args[ 'child_of' ] = icl_object_id( $args[ 'child_of' ], 'page', true );
  6536. $args_updated = true;
  6537. }
  6538. if ( $args_updated ) {
  6539. remove_filter( 'get_pages', array( $this, 'get_pages_adjust_ids' ), 1 );
  6540. $pages = get_pages( $args );
  6541. add_filter( 'get_pages', array( $this, 'get_pages_adjust_ids' ), 1, 2 );
  6542. }
  6543. wp_cache_set($cache_key, $pages, $cache_group);
  6544. } else {
  6545. $pages = $cached_result;
  6546. }
  6547. }
  6548. return $pages;
  6549. }
  6550. function category_link_adjust_id( $catlink, $cat_id )
  6551. {
  6552. global $icl_adjust_id_url_filter_off, $wpdb;
  6553. if ( $icl_adjust_id_url_filter_off )
  6554. return $catlink; // special cases when we need the categiry in a different language
  6555. $translated_id = icl_object_id( $cat_id, 'category', true );
  6556. if ( $translated_id && $translated_id != $cat_id ) {
  6557. $translated_id = $wpdb->get_var( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id='{$translated_id}'" );
  6558. remove_filter( 'category_link', array( $this, 'category_link_adjust_id' ), 1 );
  6559. $catlink = get_category_link( $translated_id, 'category' );
  6560. add_filter( 'category_link', array( $this, 'category_link_adjust_id' ), 1, 2 );
  6561. }
  6562. return $catlink;
  6563. }
  6564. // adjacent posts links
  6565. function get_adjacent_post_join( $join )
  6566. {
  6567. global $wpdb;
  6568. $post_type = get_query_var( 'post_type' );
  6569. $cache_key = md5( json_encode( array( $post_type, $join ) ) );
  6570. $cache_group = 'adjacent_post_join';
  6571. $temp_join = wp_cache_get( $cache_key, $cache_group );
  6572. if ( $temp_join ) {
  6573. return $temp_join;
  6574. }
  6575. if ( !$post_type ) {
  6576. $post_type = 'post';
  6577. }
  6578. if ( $this->is_translated_post_type( $post_type ) ) {
  6579. $join .= " JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type = 'post_{$post_type}'";
  6580. }
  6581. wp_cache_set( $cache_key, $join, $cache_group );
  6582. return $join;
  6583. }
  6584. function get_adjacent_post_where( $where )
  6585. {
  6586. $post_type = get_query_var( 'post_type' );
  6587. $cache_key = md5(json_encode( array( $post_type, $where ) ) );
  6588. $cache_group = 'adjacent_post_where';
  6589. $temp_where = wp_cache_get( $cache_key, $cache_group );
  6590. if ( $temp_where ) {
  6591. return $temp_where;
  6592. }
  6593. if ( !$post_type ) {
  6594. $post_type = 'post';
  6595. }
  6596. if ( $this->is_translated_post_type( $post_type ) ) {
  6597. $where .= " AND language_code = '" . esc_sql( $this->this_lang ) . "'";
  6598. }
  6599. wp_cache_set( $cache_key, $where, $cache_group );
  6600. return $where;
  6601. }
  6602. // feeds links
  6603. function feed_link( $out )
  6604. {
  6605. return $this->convert_url( $out );
  6606. }
  6607. // commenting links
  6608. function post_comments_feed_link( $out )
  6609. {
  6610. if ( $this->settings[ 'language_negotiation_type' ] == 3 ) {
  6611. $out = preg_replace( '@(\?|&)lang=([^/]+)/feed/@i', 'feed/$1lang=$2', $out );
  6612. }
  6613. return $out;
  6614. //return $this->convert_url($out);
  6615. }
  6616. function trackback_url( $out )
  6617. {
  6618. return $this->convert_url( $out );
  6619. }
  6620. function user_trailingslashit( $string, $type_of_url )
  6621. {
  6622. // fixes comment link for when the comments list pagination is enabled
  6623. if ( $type_of_url == 'comment' ) {
  6624. $string = preg_replace( '@(.*)/\?lang=([a-z-]+)/(.*)@is', '$1/$3?lang=$2', $string );
  6625. }
  6626. return $string;
  6627. }
  6628. // archives links
  6629. function getarchives_join( $join )
  6630. {
  6631. global $wpdb;
  6632. $join .= " JOIN {$wpdb->prefix}icl_translations t ON t.element_id = {$wpdb->posts}.ID AND t.element_type='post_post'";
  6633. return $join;
  6634. }
  6635. function getarchives_where( $where )
  6636. {
  6637. $where .= " AND language_code = '" . esc_sql( $this->this_lang ) . "'";
  6638. return $where;
  6639. }
  6640. function archives_link( $out )
  6641. {
  6642. global $icl_archive_url_filter_off;
  6643. if ( !$icl_archive_url_filter_off ) {
  6644. $out = $this->archive_url( $out, $this->this_lang );
  6645. }
  6646. $icl_archive_url_filter_off = false;
  6647. return $out;
  6648. }
  6649. function archive_url( $url, $lang )
  6650. {
  6651. $url = $this->convert_url( $url, $lang );
  6652. return $url;
  6653. }
  6654. function author_link( $url )
  6655. {
  6656. $url = $this->convert_url( $url );
  6657. return preg_replace( '#^http://(.+)//(.+)$#', 'http://$1/$2', $url );
  6658. }
  6659. function pre_option_home( $setting = false )
  6660. {
  6661. if ( !defined( 'TEMPLATEPATH' ) )
  6662. return $setting;
  6663. $template_real_path = realpath( TEMPLATEPATH );
  6664. $debug_backtrace = $this->get_backtrace( 7 ); //Ignore objects and limit to first 7 stack frames, since 6 is the highest index we use
  6665. $inc_methods = array( 'include', 'include_once', 'require', 'require_once' );
  6666. if ( isset( $debug_backtrace[ 4 ] ) && $debug_backtrace[ 4 ][ 'function' ] == 'get_bloginfo' && isset( $debug_backtrace[ 5 ] ) && $debug_backtrace[ 5 ][ 'function' ] == 'bloginfo' ) {
  6667. // case of bloginfo
  6668. $is_template_file = false !== strpos( $debug_backtrace[ 5 ][ 'file' ], $template_real_path );
  6669. $is_direct_call = in_array( $debug_backtrace[ 6 ][ 'function' ], $inc_methods ) || ( false !== strpos( $debug_backtrace[ 6 ][ 'file' ], $template_real_path ) );
  6670. } elseif ( isset( $debug_backtrace[ 4 ] ) && $debug_backtrace[ '4' ][ 'function' ] == 'get_bloginfo' ) {
  6671. // case of get_bloginfo
  6672. $is_template_file = false !== strpos( $debug_backtrace[ 4 ][ 'file' ], $template_real_path );
  6673. $is_direct_call = in_array( $debug_backtrace[ 5 ][ 'function' ], $inc_methods ) || ( false !== strpos( $debug_backtrace[ 5 ][ 'file' ], $template_real_path ) );
  6674. } elseif ( isset( $debug_backtrace[ 4 ] ) && $debug_backtrace[ '4' ][ 'function' ] == 'get_settings' ) {
  6675. // case of get_settings
  6676. $is_template_file = false !== strpos( $debug_backtrace[ 4 ][ 'file' ], $template_real_path );
  6677. $is_direct_call = in_array( $debug_backtrace[ 5 ][ 'function' ], $inc_methods ) || ( false !== strpos( $debug_backtrace[ 5 ][ 'file' ], $template_real_path ) );
  6678. } else {
  6679. // case of get_option
  6680. $is_template_file = isset( $debug_backtrace[ 3 ][ 'file' ] ) && ( false !== strpos( $debug_backtrace[ 3 ][ 'file' ], $template_real_path ) );
  6681. $is_direct_call = isset( $debug_backtrace[ 4 ] ) && in_array( $debug_backtrace[ 4 ][ 'function' ], $inc_methods ) || ( isset( $debug_backtrace[ 4 ][ 'file' ] ) && false !== strpos( $debug_backtrace[ 4 ][ 'file' ], $template_real_path ) );
  6682. }
  6683. //if($dbbt[3]['file'] == @realpath(TEMPLATEPATH . '/header.php')){
  6684. if ( $is_template_file && $is_direct_call ) {
  6685. $ret = $this->language_url( $this->this_lang );
  6686. } else {
  6687. $ret = $setting;
  6688. }
  6689. return $ret;
  6690. }
  6691. function query_vars( $public_query_vars )
  6692. {
  6693. $public_query_vars[ ] = 'lang';
  6694. global $wp_query;
  6695. $wp_query->query_vars[ 'lang' ] = $this->this_lang;
  6696. return $public_query_vars;
  6697. }
  6698. function parse_query( $q )
  6699. {
  6700. global $wp_query, $wpdb;
  6701. //if($q == $wp_query) return; // not touching the WP query
  6702. if ( is_admin() ) {
  6703. return $q;
  6704. }
  6705. $current_language = $this->get_current_language();
  6706. $default_language = $this->get_default_language();
  6707. if ( $current_language != $default_language ) {
  6708. $cat_array = array();
  6709. // cat
  6710. if ( isset( $q->query_vars[ 'cat' ] ) && !empty( $q->query_vars[ 'cat' ] ) ) {
  6711. $cat_array = array_map( 'intval', array_map( 'trim', explode( ',', $q->query_vars[ 'cat' ] ) ) );
  6712. }
  6713. // category_name
  6714. if ( isset( $q->query_vars[ 'category_name' ] ) && !empty( $q->query_vars[ 'category_name' ] ) ) {
  6715. $categories = explode(",", $q->query_vars[ 'category_name' ] );
  6716. $cat_array = array();
  6717. foreach ($categories as $category) {
  6718. $category = trim($category);
  6719. if ($category == "") { // it happens for category_name = "some-cat,some-cat-2,", with comma at end
  6720. continue;
  6721. }
  6722. $cat = get_term_by( 'slug', preg_replace( '#((.*)/)#', '', $category), 'category' );
  6723. if ( !$cat ) {
  6724. $cat = get_term_by( 'name', $category, 'category' );
  6725. }
  6726. if ( isset($cat) && is_object($cat) && $cat->term_id ) {
  6727. $cat_array[] = $cat->term_id;
  6728. }
  6729. }
  6730. if (empty($cat_array)) {
  6731. $q->query_vars[ 'p' ] = -1;
  6732. }
  6733. }
  6734. // category_and
  6735. if ( isset( $q->query_vars[ 'category__and' ] ) && !empty( $q->query_vars[ 'category__and' ] ) ) {
  6736. $cat_array = $q->query_vars[ 'category__and' ];
  6737. }
  6738. // category_in
  6739. if ( isset( $q->query_vars[ 'category__in' ] ) && !empty( $q->query_vars[ 'category__in' ] ) ) {
  6740. $cat_array = array_unique( array_merge( $cat_array, array_map( 'intval', $q->query_vars[ 'category__in' ] ) ) );
  6741. }
  6742. // category__not_in
  6743. if ( isset( $q->query_vars[ 'category__not_in' ] ) && !empty( $q->query_vars[ 'category__not_in' ] ) ) {
  6744. $__cats = array_map( create_function( '$a', 'return -1*intval($a);' ), $q->query_vars[ 'category__not_in' ] );
  6745. $cat_array = array_unique( array_merge( $cat_array, $__cats ) );
  6746. }
  6747. if ( !empty( $cat_array ) ) {
  6748. $translated_ids = array();
  6749. foreach ( $cat_array as $c ) {
  6750. if ( intval( $c ) < 0 ) {
  6751. $sign = -1;
  6752. } else {
  6753. $sign = 1;
  6754. }
  6755. $translated_ids[ ] = $sign * intval( icl_object_id( abs( $c ), 'category', true ) );
  6756. }
  6757. //cat
  6758. if ( isset( $q->query_vars[ 'cat' ] ) && !empty( $q->query_vars[ 'cat' ] ) ) {
  6759. $q->query_vars[ 'cat' ] = join( ',', $translated_ids );
  6760. }
  6761. // category_name
  6762. if ( isset( $q->query_vars[ 'category_name' ] ) && !empty( $q->query_vars[ 'category_name' ] ) ) {
  6763. $_ctmp = get_term_by( 'id', $translated_ids[ 0 ], 'category' );
  6764. $q->query_vars[ 'category_name' ] = $_ctmp->slug;
  6765. }
  6766. // category__and
  6767. if ( isset( $q->query_vars[ 'category__and' ] ) && !empty( $q->query_vars[ 'category__and' ] ) ) {
  6768. $q->query_vars[ 'category__and' ] = $translated_ids;
  6769. }
  6770. // category__in
  6771. if ( isset( $q->query_vars[ 'category__in' ] ) && !empty( $q->query_vars[ 'category__in' ] ) ) {
  6772. $q->query_vars[ 'category__in' ] = array_filter( $translated_ids, create_function( '$a', 'return $a>0;' ) );
  6773. }
  6774. // category__not_in
  6775. if ( isset( $q->query_vars[ 'category__not_in' ] ) && !empty( $q->query_vars[ 'category__not_in' ] ) ) {
  6776. $q->query_vars[ 'category__not_in' ] = array_filter( $translated_ids, create_function( '$a', 'return $a<0;' ) );
  6777. }
  6778. }
  6779. // TAGS
  6780. $tag_array = array();
  6781. // tag
  6782. $tag_glue = '';
  6783. if ( isset( $q->query_vars[ 'tag' ] ) && !empty( $q->query_vars[ 'tag' ] ) ) {
  6784. if ( false !== strpos( $q->query_vars[ 'tag' ], ' ' ) ) {
  6785. $tag_glue = '+';
  6786. $exp = explode( ' ', $q->query_vars[ 'tag' ] );
  6787. } else {
  6788. $tag_glue = ',';
  6789. $exp = explode( ',', $q->query_vars[ 'tag' ] );
  6790. }
  6791. foreach ( $exp as $e ) {
  6792. $tag_array[ ] = $wpdb->get_var( $wpdb->prepare( "SELECT x.term_id FROM $wpdb->terms t
  6793. JOIN $wpdb->term_taxonomy x ON t.term_id=x.term_id WHERE x.taxonomy='post_tag' AND t.slug=%s", $e ) );
  6794. }
  6795. $_tmp = array_unique( $tag_array );
  6796. if ( count( $_tmp ) == 1 && empty( $_tmp[ 0 ] ) ) {
  6797. $tag_array = array();
  6798. }
  6799. }
  6800. // tag_id
  6801. if ( isset( $q->query_vars[ 'tag_id' ] ) && !empty( $q->query_vars[ 'tag_id' ] ) ) {
  6802. $tag_array = array_map( 'trim', explode( ',', $q->query_vars[ 'tag_id' ] ) );
  6803. }
  6804. // tag__and
  6805. if ( isset( $q->query_vars[ 'tag__and' ] ) && !empty( $q->query_vars[ 'tag__and' ] ) ) {
  6806. $tag_array = $q->query_vars[ 'tag__and' ];
  6807. }
  6808. // tag__in
  6809. if ( isset( $q->query_vars[ 'tag__in' ] ) && !empty( $q->query_vars[ 'tag__in' ] ) ) {
  6810. $tag_array = $q->query_vars[ 'tag__in' ];
  6811. }
  6812. // tag__not_in
  6813. if ( isset( $q->query_vars[ 'tag__not_in' ] ) && !empty( $q->query_vars[ 'tag__not_in' ] ) ) {
  6814. $tag_array = $q->query_vars[ 'tag__not_in' ];
  6815. }
  6816. // tag_slug__in
  6817. if ( isset( $q->query_vars[ 'tag_slug__in' ] ) && !empty( $q->query_vars[ 'tag_slug__in' ] ) ) {
  6818. foreach ( $q->query_vars[ 'tag_slug__in' ] as $t ) {
  6819. if ( $tg = $wpdb->get_var( $wpdb->prepare( "
  6820. SELECT x.term_id FROM $wpdb->terms t
  6821. JOIN $wpdb->term_taxonomy x ON t.term_id=x.term_id
  6822. WHERE x.taxonomy='post_tag' AND t.slug=%s", $t ) )
  6823. ) {
  6824. $tag_array[ ] = $tg;
  6825. }
  6826. }
  6827. }
  6828. // tag_slug__and
  6829. if ( isset( $q->query_vars[ 'tag_slug__and' ] ) && !empty( $q->query_vars[ 'tag_slug__and' ] ) ) {
  6830. foreach ( $q->query_vars[ 'tag_slug__and' ] as $t ) {
  6831. $tag_array[ ] = $wpdb->get_var( $wpdb->prepare( "SELECT x.term_id FROM $wpdb->terms t
  6832. JOIN $wpdb->term_taxonomy x ON t.term_id=x.term_id WHERE x.taxonomy='post_tag' AND t.slug=%s", $t ) );
  6833. }
  6834. }
  6835. if ( !empty( $tag_array ) ) {
  6836. $translated_ids = array();
  6837. foreach ( $tag_array as $c ) {
  6838. if ( intval( $c ) < 0 ) {
  6839. $sign = -1;
  6840. } else {
  6841. $sign = 1;
  6842. }
  6843. $_tid = intval( icl_object_id( abs( $c ), 'post_tag', true ) );
  6844. $translated_ids[ ] = $sign * $_tid;
  6845. }
  6846. }
  6847. if ( !empty( $translated_ids ) ) {
  6848. //tag
  6849. if ( isset( $q->query_vars[ 'tag' ] ) && !empty( $q->query_vars[ 'tag' ] ) ) {
  6850. $slugs = $wpdb->get_col( "SELECT slug FROM $wpdb->terms WHERE term_id IN (" . join( ',', $translated_ids ) . ")" );
  6851. $q->query_vars[ 'tag' ] = join( $tag_glue, $slugs );
  6852. }
  6853. //tag_id
  6854. if ( isset( $q->query_vars[ 'tag_id' ] ) && !empty( $q->query_vars[ 'tag_id' ] ) ) {
  6855. $q->query_vars[ 'tag_id' ] = join( ',', $translated_ids );
  6856. }
  6857. // tag__and
  6858. if ( isset( $q->query_vars[ 'tag__and' ] ) && !empty( $q->query_vars[ 'tag__and' ] ) ) {
  6859. $q->query_vars[ 'tag__and' ] = $translated_ids;
  6860. }
  6861. // tag__in
  6862. if ( isset( $q->query_vars[ 'tag__in' ] ) && !empty( $q->query_vars[ 'tag__in' ] ) ) {
  6863. $q->query_vars[ 'tag__in' ] = $translated_ids;
  6864. }
  6865. // tag__not_in
  6866. if ( isset( $q->query_vars[ 'tag__not_in' ] ) && !empty( $q->query_vars[ 'tag__not_in' ] ) ) {
  6867. $q->query_vars[ 'tag__not_in' ] = array_map( 'abs', $translated_ids );
  6868. }
  6869. // tag_slug__in
  6870. if ( isset( $q->query_vars[ 'tag_slug__in' ] ) && !empty( $q->query_vars[ 'tag_slug__in' ] ) ) {
  6871. $q->query_vars[ 'tag_slug__in' ] = $wpdb->get_col( "SELECT slug FROM $wpdb->terms WHERE term_id IN (" . join( ',', $translated_ids ) . ")" );
  6872. }
  6873. // tag_slug__and
  6874. if ( isset( $q->query_vars[ 'tag_slug__and' ] ) && !empty( $q->query_vars[ 'tag_slug__and' ] ) ) {
  6875. $q->query_vars[ 'tag_slug__and' ] = $wpdb->get_col( "SELECT slug FROM $wpdb->terms WHERE term_id IN (" . join( ',', $translated_ids ) . ")" );
  6876. }
  6877. }
  6878. // POST & PAGES
  6879. $post_type = !empty( $q->query_vars[ 'post_type' ] ) ? $q->query_vars[ 'post_type' ] : 'post';
  6880. if(!is_array($post_type)) {
  6881. $post_type = (array)$post_type;
  6882. }
  6883. // page_id
  6884. if ( isset( $q->query_vars[ 'page_id' ] ) && !empty( $q->query_vars[ 'page_id' ] ) ) {
  6885. $q->query_vars[ 'page_id' ] = icl_object_id( $q->query_vars[ 'page_id' ], 'page', true );
  6886. $q->query = preg_replace( '/page_id=[0-9]+/', 'page_id=' . $q->query_vars[ 'page_id' ], $q->query );
  6887. }
  6888. // Adjust included IDs adjusting them with translated element, if present
  6889. if ( isset( $q->query_vars[ 'include' ] ) && !empty( $q->query_vars[ 'include' ] ) ) {
  6890. $include_arr = is_array( $q->query_vars[ 'include' ] ) ? $q->query_vars[ 'include' ] : explode( ',', $q->query_vars[ 'include' ] );
  6891. $include_arr_adjusted = array();
  6892. foreach ( $include_arr as $include_arr_id ) {
  6893. $include_arr_adjusted[ ] = icl_object_id( $include_arr_id, get_post_type($include_arr_id), true );
  6894. }
  6895. $q->query_vars[ 'include' ] = is_array( $q->query_vars[ 'include' ] ) ? $include_arr_adjusted : implode( ',', $include_arr_adjusted );
  6896. }
  6897. // Adjust excluded IDs adjusting them with translated element, if present
  6898. if ( isset( $q->query_vars[ 'exclude' ] ) && !empty( $q->query_vars[ 'exclude' ] ) ) {
  6899. $exclude_arr = is_array( $q->query_vars[ 'exclude' ] ) ? $q->query_vars[ 'exclude' ] : explode( ',', $q->query_vars[ 'exclude' ] );
  6900. $exclude_arr_adjusted = array();
  6901. foreach ( $exclude_arr as $exclude_arr_id ) {
  6902. $exclude_arr_adjusted[ ] = icl_object_id( $exclude_arr_id, get_post_type($exclude_arr_id), true );
  6903. }
  6904. $q->query_vars[ 'exclude' ] = is_array( $q->query_vars[ 'exclude' ] ) ? $exclude_arr_adjusted : implode( ',', $exclude_arr_adjusted );
  6905. }
  6906. // Adjust post id
  6907. if ( isset( $q->query_vars[ 'p' ] ) && !empty( $q->query_vars[ 'p' ] ) ) {
  6908. $q->query_vars[ 'p' ] = icl_object_id( $q->query_vars[ 'p' ], $post_type[0], true );
  6909. }
  6910. // Adjust name
  6911. if ( $this->is_translated_post_type($post_type[0]) && isset( $q->query_vars[ 'name' ] ) && !empty( $q->query_vars[ 'name' ] ) ) {
  6912. $pid_prepared = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_name=%s AND post_type=%s", array($q->query_vars[ 'name' ], $post_type[0]));
  6913. $pid = $wpdb->get_var( $pid_prepared );
  6914. if ( !empty( $pid ) ) {
  6915. $q->query_vars[ 'p' ] = icl_object_id( $pid, $post_type[0], true );
  6916. unset( $q->query_vars[ 'name' ] );
  6917. }
  6918. }
  6919. // Adjust page name
  6920. if ( isset( $q->query_vars[ 'pagename' ] ) && !empty( $q->query_vars[ 'pagename' ] ) ) {
  6921. // find the page with the page name in the current language.
  6922. $pid = $wpdb->get_var( $wpdb->prepare( "
  6923. SELECT ID
  6924. FROM $wpdb->posts p
  6925. JOIN {$wpdb->prefix}icl_translations t
  6926. ON p.ID = t.element_id AND element_type='post_page'
  6927. WHERE p.post_name=%s AND t.language_code = %s
  6928. ", $q->query_vars[ 'pagename' ], $current_language ) );
  6929. if ( $pid ) {
  6930. $q->query_vars[ 'page_id' ] = $pid;
  6931. // We have found the page id
  6932. unset( $q->query_vars[ 'pagename' ] );
  6933. if ( $q->query_vars[ 'page_id' ] == get_option( 'page_for_posts' ) ) {
  6934. // it's the blog page.
  6935. $q->is_page = false; // $wp_query->is_page = false;
  6936. $q->is_home = true; // $wp_query->is_home = true;
  6937. $q->is_posts_page = true; // $wp_query->is_posts_page = true;
  6938. }
  6939. }
  6940. }
  6941. // post__in
  6942. if ( isset( $q->query_vars[ 'post__in' ] ) && !empty( $q->query_vars[ 'post__in' ] ) ) {
  6943. $pid = array();
  6944. foreach ( $q->query_vars[ 'post__in' ] as $p ) {
  6945. if ( $post_type ) {
  6946. foreach ( $post_type as $pt ) {
  6947. $pid[ ] = icl_object_id( $p, $pt, true );
  6948. }
  6949. }
  6950. }
  6951. $q->query_vars[ 'post__in' ] = $pid;
  6952. }
  6953. // post__not_in
  6954. if ( isset( $q->query_vars[ 'post__not_in' ] ) && !empty( $q->query_vars[ 'post__not_in' ] ) ) {
  6955. $pid = array();
  6956. foreach ( $q->query_vars[ 'post__not_in' ] as $p ) {
  6957. if ( $post_type ) {
  6958. foreach ( $post_type as $pt ) {
  6959. $pid[ ] = icl_object_id( $p, $pt, true );
  6960. }
  6961. }
  6962. }
  6963. $q->query_vars[ 'post__not_in' ] = $pid;
  6964. }
  6965. // post_parent
  6966. if ( isset( $q->query_vars[ 'post_parent' ] ) && !empty( $q->query_vars[ 'post_parent' ] ) && $q->query_vars[ 'post_type' ] != 'attachment' ) {
  6967. if ( $post_type ) {
  6968. $_parent_type = $wpdb->get_var( $wpdb->prepare( "SELECT post_type FROM {$wpdb->posts} WHERE ID=%d", $q->query_vars[ 'post_parent' ] ) );
  6969. $q->query_vars[ 'post_parent' ] = icl_object_id( $q->query_vars[ 'post_parent' ], $_parent_type, true );
  6970. }
  6971. }
  6972. // custom taxonomies
  6973. if ( isset( $q->query_vars[ 'taxonomy' ] ) && $q->query_vars[ 'taxonomy' ] ) {
  6974. $tax_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->terms} WHERE slug=%s", $q->query_vars[ 'term' ] ) );
  6975. if ( $tax_id ) {
  6976. $translated_tax_id = icl_object_id( $tax_id, $q->query_vars[ 'taxonomy' ], true );
  6977. }
  6978. if ( isset( $translated_tax_id ) ) {
  6979. $q->query_vars[ 'term' ] = $wpdb->get_var( $wpdb->prepare( "SELECT slug FROM {$wpdb->terms} WHERE term_id = %d", $translated_tax_id ) );
  6980. $q->query[ $q->query_vars[ 'taxonomy' ] ] = $q->query_vars[ 'term' ];
  6981. }
  6982. }
  6983. // TODO Discuss this. Why WP assumes it's there if query vars are altered?
  6984. // Look at wp-includes/query.php line #2468 search: if ( $this->query_vars_changed ) {
  6985. if ( !isset( $q->query_vars[ 'meta_query' ] ) ) {
  6986. $q->query_vars[ 'meta_query' ] = array();
  6987. }
  6988. if ( isset( $q->query_vars[ 'tax_query' ] ) && is_array( $q->query_vars[ 'tax_query' ] ) ) {
  6989. foreach ( $q->query[ 'tax_query' ] as $num => $fields ) {
  6990. if ( ! isset( $fields[ 'terms' ] ) ) {
  6991. continue;
  6992. }
  6993. if ( is_array( $fields[ 'terms' ] ) ) {
  6994. foreach ( $fields[ 'terms' ] as $term ) {
  6995. $taxonomy = get_term_by( $fields[ 'field' ], $term, $fields[ 'taxonomy' ] );
  6996. if ( is_object( $taxonomy ) ) {
  6997. if ( $fields[ 'field' ] == 'id' ) {
  6998. $field = isset($taxonomy->term_id) ? $taxonomy->term_id : null;
  6999. } else {
  7000. $field = isset($taxonomy->{$fields[ 'field' ]}) ? $taxonomy->{$fields[ 'field' ]} : null;
  7001. }
  7002. //$q->query[ 'tax_query' ][ $num ][ 'terms' ] = array_diff( $q->query[ 'tax_query' ][ $num ][ 'terms' ], array( $term ) ); // removes from array element with original value
  7003. //$q->query[ 'tax_query' ][ $num ][ 'terms' ][ ] = $field;
  7004. //
  7005. //$q->tax_query->queries[ $num ][ 'terms' ] = array_diff( $q->tax_query->queries[ $num ][ 'terms' ], array( $term ) ); // see above
  7006. //$q->tax_query->queries[ $num ][ 'terms' ][ ] = $field;
  7007. //
  7008. //$q->query_vars[ 'tax_query' ][ $num ][ 'terms' ] = array_diff( $q->query_vars[ 'tax_query' ][ $num ][ 'terms' ], array( $term ) ); // see above
  7009. //$q->query_vars[ 'tax_query' ][ $num ][ 'terms' ][ ] = $field;
  7010. $tmp = $q->query[ 'tax_query' ][ $num ][ 'terms' ];
  7011. $tmp = array_diff( (array)$tmp, array( $term ) ); // removes from array element with original value
  7012. $tmp[ ] = $field;
  7013. //Reindex array
  7014. $q->query[ 'tax_query' ][ $num ][ 'terms' ] = array_values( $tmp );
  7015. if (isset($q->tax_query->queries[ $num ][ 'terms' ])) {
  7016. $tmp = $q->tax_query->queries[ $num ][ 'terms' ];
  7017. } else {
  7018. $tmp = array(); // clean $tmp variable
  7019. }
  7020. $tmp = array_diff( (array)$tmp, array( $term ) ); // see above
  7021. $tmp[ ] = $field;
  7022. //Reindex array
  7023. $q->tax_query->queries[ $num ][ 'terms' ] = array_values( $tmp );
  7024. $tmp = $q->query_vars[ 'tax_query' ][ $num ][ 'terms' ];
  7025. $tmp = array_diff( (array)$tmp, array( $term ) ); // see above
  7026. $tmp[ ] = $field;
  7027. //Reindex array
  7028. $q->query_vars[ 'tax_query' ][ $num ][ 'terms' ] = array_values( $tmp );
  7029. if ($fields['field'] == 'id') {
  7030. $field = $taxonomy->term_id;
  7031. } else {
  7032. $field = $taxonomy->{$fields[ 'field' ]};
  7033. }
  7034. unset( $tmp );
  7035. }
  7036. }
  7037. } else if ( is_string( $fields[ 'terms' ] ) ) {
  7038. $taxonomy = get_term_by( $fields[ 'field' ], $fields[ 'terms' ], $fields[ 'taxonomy' ] );
  7039. if ( is_object( $taxonomy ) ) {
  7040. $field = isset($taxonomy->{$fields[ 'field' ]}) ? $taxonomy->{$fields[ 'field' ]} : null;
  7041. $q->query[ 'tax_query' ][ $num ][ 'terms' ] = $field;
  7042. $q->tax_query->queries[ $num ][ 'terms' ][ 0 ] = $field;
  7043. $q->query_vars[ 'tax_query' ][ $num ][ 'terms' ] = $field;
  7044. }
  7045. }
  7046. }
  7047. }
  7048. }
  7049. return $q;
  7050. }
  7051. function adjust_wp_list_pages_excludes( $pages )
  7052. {
  7053. foreach ( $pages as $k => $v ) {
  7054. $pages[ $k ] = icl_object_id( $v, 'page', true );
  7055. }
  7056. return $pages;
  7057. }
  7058. function language_attributes( $output )
  7059. {
  7060. if ( preg_match( '#lang="[a-z-]+"#i', $output ) ) {
  7061. $output = preg_replace( '#lang="([a-z-]+)"#i', 'lang="' . $this->this_lang . '"', $output );
  7062. } else {
  7063. $output .= ' lang="' . $this->this_lang . '"';
  7064. }
  7065. return $output;
  7066. }
  7067. // Localization
  7068. function plugin_localization()
  7069. {
  7070. load_plugin_textdomain( 'sitepress', false, ICL_PLUGIN_FOLDER . '/locale' );
  7071. }
  7072. function locale()
  7073. {
  7074. global $locale;
  7075. add_filter( 'language_attributes', array( $this, '_language_attributes' ) );
  7076. $l = false;
  7077. if(defined('DOING_AJAX') && DOING_AJAX && isset($_REQUEST['action']) && isset($_REQUEST['lang'])) {
  7078. $l = $this->get_locale($_REQUEST['lang']);
  7079. }
  7080. if(!$l) {
  7081. if (defined( 'WP_ADMIN' ) ) {
  7082. if ( get_user_meta( $this->get_current_user()->ID, 'icl_admin_language_for_edit', true ) && icl_is_post_edit() ) {
  7083. $l = $this->get_locale( $this->get_current_language() );
  7084. } else {
  7085. $l = $this->get_locale( $this->admin_language );
  7086. }
  7087. } else {
  7088. $l = $this->get_locale( $this->this_lang );
  7089. }
  7090. }
  7091. if ( $l ) {
  7092. $locale = $l;
  7093. }
  7094. // theme localization
  7095. remove_filter( 'locale', array( $this, 'locale' ) ); //avoid infinite loop
  7096. static $theme_locales_loaded = false;
  7097. if ( !$theme_locales_loaded && !empty( $this->settings[ 'theme_localization_load_textdomain' ] ) && !empty( $this->settings[ 'gettext_theme_domain_name' ] ) && !empty( $this->settings[ 'theme_language_folders' ] )
  7098. ) {
  7099. foreach ( $this->settings[ 'theme_language_folders' ] as $folder ) {
  7100. load_textdomain( $this->settings[ 'gettext_theme_domain_name' ], $folder . '/' . $locale . '.mo' );
  7101. }
  7102. $theme_locales_loaded = true;
  7103. }
  7104. add_filter( 'locale', array( $this, 'locale' ) );
  7105. return $locale;
  7106. }
  7107. function _language_attributes( $latr )
  7108. {
  7109. global $locale;
  7110. $latr = preg_replace( '#lang="(.[a-z])"#i', 'lang="' . str_replace( '_', '-', $locale ) . '"', $latr );
  7111. return $latr;
  7112. }
  7113. function get_language_tag( $code )
  7114. {
  7115. global $wpdb;
  7116. static $all_tags = null;
  7117. if ( is_null( $code ) )
  7118. return false;
  7119. if ( $tag = wp_cache_get( 'icl_language_tags_' . $code ) ) {
  7120. return $tag;
  7121. }
  7122. if($all_tags==null) {
  7123. $all_tags_data = $wpdb->get_results( "SELECT code, tag FROM {$wpdb->prefix}icl_languages" );
  7124. foreach($all_tags_data as $tag_data) {
  7125. $all_tags[$tag_data->code] = $tag_data->tag;
  7126. }
  7127. }
  7128. $tag = $this->get_locale( $code );
  7129. if($all_tags) {
  7130. $tag = isset($all_tags[$code]) ? $all_tags[$code] : false;
  7131. if ( $tag ) {
  7132. wp_cache_set( 'icl_language_tags_' . $code, $tag );
  7133. }
  7134. }
  7135. return $tag;
  7136. }
  7137. function get_locale( $code )
  7138. {
  7139. global $wpdb;
  7140. $all_locales = null;
  7141. if ( is_null( $code ) )
  7142. return false;
  7143. $found = false;
  7144. $locale = wp_cache_get( 'get_locale' . $code, '', false, $found );
  7145. if ( $found ) {
  7146. return $locale;
  7147. }
  7148. $all_locales_data = $wpdb->get_results("SELECT code, locale FROM {$wpdb->prefix}icl_locale_map" );
  7149. foreach($all_locales_data as $locales_data) {
  7150. $all_locales[$locales_data->code] = $locales_data->locale;
  7151. }
  7152. $locale = isset($all_locales[$code]) ? $all_locales[$code] : false;
  7153. if ($locale == false) {
  7154. $this_locale_data = $wpdb->get_row( $wpdb->prepare("SELECT code, default_locale FROM {$wpdb->prefix}icl_languages WHERE code = '%s'", $code) );
  7155. if ($this_locale_data) {
  7156. $locale = $this_locale_data->default_locale;
  7157. }
  7158. }
  7159. wp_cache_set( 'get_locale' . $code, $locale );
  7160. return $locale;
  7161. }
  7162. function switch_locale( $lang_code = false )
  7163. {
  7164. global $l10n;
  7165. static $original_l10n;
  7166. if ( !empty( $lang_code ) ) {
  7167. $original_l10n = $l10n[ 'sitepress' ];
  7168. unset( $l10n[ 'sitepress' ] );
  7169. load_textdomain( 'sitepress', ICL_PLUGIN_PATH . '/locale/sitepress-' . $this->get_locale( $lang_code ) . '.mo' );
  7170. } else { // switch back
  7171. $l10n[ 'sitepress' ] = $original_l10n;
  7172. }
  7173. }
  7174. function get_locale_file_names()
  7175. {
  7176. global $wpdb;
  7177. $locales = array();
  7178. $res = $wpdb->get_results( "
  7179. SELECT lm.code, locale
  7180. FROM {$wpdb->prefix}icl_locale_map lm JOIN {$wpdb->prefix}icl_languages l ON lm.code = l.code AND l.active=1" );
  7181. foreach ( $res as $row ) {
  7182. $locales[ $row->code ] = $row->locale;
  7183. }
  7184. return $locales;
  7185. }
  7186. function set_locale_file_names( $locale_file_names_pairs )
  7187. {
  7188. global $wpdb;
  7189. $lfn = $this->get_locale_file_names();
  7190. $new = array_diff( array_keys( $locale_file_names_pairs ), array_keys( $lfn ) );
  7191. if ( !empty( $new ) ) {
  7192. foreach ( $new as $code ) {
  7193. $wpdb->insert( $wpdb->prefix . 'icl_locale_map', array( 'code' => $code, 'locale' => $locale_file_names_pairs[ $code ] ) );
  7194. }
  7195. }
  7196. $remove = array_diff( array_keys( $lfn ), array_keys( $locale_file_names_pairs ) );
  7197. if ( !empty( $remove ) ) {
  7198. $wpdb->query( "DELETE FROM {$wpdb->prefix}icl_locale_map WHERE code IN (" . join( ',', array_map( create_function( '$a', 'return "\'".$a."\'";' ), $remove ) ) . ")" );
  7199. }
  7200. $update = array_diff( $locale_file_names_pairs, $lfn );
  7201. foreach ( $update as $code => $locale ) {
  7202. $wpdb->update( $wpdb->prefix . 'icl_locale_map', array( 'locale' => $locale ), array( 'code' => $code ) );
  7203. }
  7204. $this->icl_locale_cache->clear();
  7205. return true;
  7206. }
  7207. function pre_option_page_on_front() {
  7208. global $wpdb;
  7209. $result = null;
  7210. static $page_on_front = null;
  7211. if ($page_on_front===false || ($GLOBALS[ 'pagenow' ] == 'site-new.php' && isset( $_REQUEST[ 'action' ] ) && 'add-site' == $_REQUEST[ 'action' ] )) {
  7212. return false;
  7213. }
  7214. $cache_key = $this->this_lang;
  7215. $cache_group = 'pre_option_page_on_front';
  7216. $found = false;
  7217. $result = wp_cache_get( $cache_key, $cache_group, false, $found );
  7218. if ( !$found || $result == false || ICL_DISABLE_CACHE ) {
  7219. $result = false;
  7220. $page_on_front = $wpdb->get_var( "SELECT option_value FROM {$wpdb->options} WHERE option_name='page_on_front'" );
  7221. if ( $page_on_front ) {
  7222. $_el_lang_det = $this->get_element_language_details( $page_on_front, 'post_page' );
  7223. if ($_el_lang_det && !empty( $_el_lang_det->trid ) ) {
  7224. $trid = $_el_lang_det->trid;
  7225. $translations = $wpdb->get_results( $wpdb->prepare("SELECT element_id, language_code FROM {$wpdb->prefix}icl_translations WHERE trid=%d", $trid ));
  7226. foreach ( $translations as $t ) {
  7227. if ( $t->language_code == $this->this_lang ) {
  7228. $result = $t->element_id;
  7229. $page = get_post( $result );
  7230. if ( !$page || $page->post_type != 'page' ) {
  7231. $result = false;
  7232. }
  7233. }
  7234. $cache_key = $t->language_code;
  7235. $found = false;
  7236. wp_cache_get( $cache_key, $cache_group, false, $found );
  7237. if ( !$found && $result !== false ) {
  7238. wp_cache_set( $cache_key, $result, $cache_group );
  7239. }
  7240. }
  7241. }
  7242. return $result;
  7243. }
  7244. }
  7245. return $result;
  7246. }
  7247. function pre_option_page_for_posts() {
  7248. global $wpdb;
  7249. static $page_for_posts = null;
  7250. static $result = null;
  7251. if ($page_for_posts===false || $result != null ) {
  7252. return $result;
  7253. }
  7254. $cache_key = $this->this_lang;
  7255. $cache_group = 'pre_option_page_for_posts';
  7256. $found = false;
  7257. $result = wp_cache_get($cache_key, $cache_group, false, $found);
  7258. if ( !$found || ICL_DISABLE_CACHE ) {
  7259. $page_for_posts = $wpdb->get_var( "SELECT option_value FROM {$wpdb->options} WHERE option_name='page_for_posts'" );
  7260. $result = false;
  7261. if ( $page_for_posts ) {
  7262. $_el_lang_det = $this->get_element_language_details( $page_for_posts, 'post_page' );
  7263. if ($_el_lang_det && !empty( $_el_lang_det->trid ) ) {
  7264. $trid = $_el_lang_det->trid;
  7265. $translations = $wpdb->get_results( $wpdb->prepare("SELECT element_id, language_code FROM {$wpdb->prefix}icl_translations WHERE trid=%d", $trid ));
  7266. foreach ( $translations as $t ) {
  7267. if ( $t->language_code == $this->this_lang ) {
  7268. $result = $t->element_id;
  7269. }
  7270. //Cache all translations
  7271. $cache_key = $t->language_code;
  7272. wp_cache_set( $cache_key, $result, $cache_group );
  7273. }
  7274. return $result;
  7275. }
  7276. }
  7277. }
  7278. return $result;
  7279. }
  7280. function verify_home_and_blog_pages_translations()
  7281. {
  7282. global $wpdb;
  7283. $warn_home = $warn_posts = '';
  7284. $page_on_front = get_option( 'page_on_front' );
  7285. if ( 'page' == get_option( 'show_on_front' ) && $page_on_front ) {
  7286. $page_home_trid = $wpdb->get_var( "SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id={$page_on_front} AND element_type='post_page'" );
  7287. $page_home_translations = $this->get_element_translations( $page_home_trid, 'post_page' );
  7288. $missing_home = array();
  7289. foreach ( $this->active_languages as $lang ) {
  7290. if ( !isset( $page_home_translations[ $lang[ 'code' ] ] ) ) {
  7291. $missing_home[ ] = $lang[ 'display_name' ];
  7292. } elseif ( $page_home_translations[ $lang[ 'code' ] ]->post_status != 'publish' ) {
  7293. $missing_home[ ] = $lang[ 'display_name' ];
  7294. }
  7295. }
  7296. if ( !empty( $missing_home ) ) {
  7297. $warn_home = '<div class="icl_form_errors" style="font-weight:bold">';
  7298. $warn_home .= sprintf( __( 'Your home page does not exist or its translation is not published in %s.', 'sitepress' ), join( ', ', $missing_home ) );
  7299. $warn_home .= '<br />';
  7300. $warn_home .= '<a href="' . get_edit_post_link( $page_on_front ) . '">' . __( 'Edit this page to add translations', 'sitepress' ) . '</a>';
  7301. $warn_home .= '</div>';
  7302. }
  7303. }
  7304. if ( get_option( 'page_for_posts' ) ) {
  7305. $page_for_posts = get_option( 'page_for_posts' );
  7306. $page_posts_trid = $wpdb->get_var( "SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id={$page_for_posts} AND element_type='post_page'" );
  7307. $page_posts_translations = $this->get_element_translations( $page_posts_trid, 'post_page' );
  7308. $missing_posts = array();
  7309. foreach ( $this->active_languages as $lang ) {
  7310. if ( !isset( $page_posts_translations[ $lang[ 'code' ] ] ) ) {
  7311. $missing_posts[ ] = $lang[ 'display_name' ];
  7312. } elseif ( $page_posts_translations[ $lang[ 'code' ] ]->post_status != 'publish' ) {
  7313. $missing_posts[ ] = $lang[ 'display_name' ];
  7314. }
  7315. }
  7316. if ( !empty( $missing_posts ) ) {
  7317. $warn_posts = '<div class="icl_form_errors" style="font-weight:bold;margin-top:4px;">';
  7318. $warn_posts .= sprintf( __( 'Your blog page does not exist or its translation is not published in %s.', 'sitepress' ), join( ', ', $missing_posts ) );
  7319. $warn_posts .= '<br />';
  7320. $warn_posts .= '<a href="' . get_edit_post_link( $page_for_posts ) . '">' . __( 'Edit this page to add translations', 'sitepress' ) . '</a>';
  7321. $warn_posts .= '</div>';
  7322. }
  7323. }
  7324. return array( $warn_home, $warn_posts );
  7325. }
  7326. // adds the language parameter to the admin post filtering/search
  7327. function restrict_manage_posts()
  7328. {
  7329. echo '<input type="hidden" name="lang" value="' . $this->this_lang . '" />';
  7330. }
  7331. // adds the language parameter to the admin pages search
  7332. function restrict_manage_pages()
  7333. {
  7334. ?>
  7335. <script type="text/javascript">
  7336. addLoadEvent(function () {
  7337. jQuery('p.search-box').append('<input type="hidden" name="lang" value="<?php echo $this->this_lang ?>">');
  7338. });
  7339. </script>
  7340. <?php
  7341. }
  7342. function get_edit_post_link( $link, $id, $context = 'display' )
  7343. {
  7344. global $wpdb;
  7345. $_cache_key = $link . '|' . $id . '|' . $context;
  7346. $cached_edit_post_link = wp_cache_get($_cache_key, 'icl_get_edit_post_link');
  7347. if ( $cached_edit_post_link ) {
  7348. $link = $cached_edit_post_link;
  7349. } else {
  7350. if ( current_user_can( 'edit_post', $id ) ) {
  7351. if ( 'display' == $context )
  7352. $and = '&amp;'; else
  7353. $and = '&';
  7354. if ( $id ) {
  7355. $post_type = $wpdb->get_var( "SELECT post_type FROM {$wpdb->posts} WHERE ID='{$id}'" );
  7356. $details = $this->get_element_language_details( $id, 'post_' . $post_type );
  7357. if ( isset( $details->language_code ) ) {
  7358. $lang = $details->language_code;
  7359. } else {
  7360. $lang = $this->get_current_language();
  7361. }
  7362. $link .= $and . 'lang=' . $lang;
  7363. }
  7364. }
  7365. wp_cache_set($_cache_key , $link,'icl_get_edit_post_link');
  7366. }
  7367. return $link;
  7368. }
  7369. function get_edit_term_link( $link, $term_id, $taxonomy, $object_type )
  7370. {
  7371. global $wpdb;
  7372. $default_language = $this->get_default_language();
  7373. $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 ) );
  7374. $details = $this->get_element_language_details( $term_tax_id, 'tax_' . $taxonomy );
  7375. $and = '&';
  7376. $current_language = $this->get_current_language();
  7377. if ( isset( $details->language_code ) ) {
  7378. $lang = $details->language_code;
  7379. } else {
  7380. $lang = $current_language;
  7381. }
  7382. if ( $lang != $default_language || $current_language != $default_language ) {
  7383. $link .= $and . 'lang=' . $lang;
  7384. }
  7385. return $link;
  7386. }
  7387. function option_sticky_posts( $posts ) {
  7388. global $wpdb;
  7389. if ( is_array( $posts ) && !empty( $posts ) ) {
  7390. $md5_posts = md5( json_encode( $posts ) );
  7391. $cache_key = $this->this_lang . ':' . $md5_posts;
  7392. $cache_group = 'icl_option_sticky_posts';
  7393. $cached_sticky_posts = wp_cache_get( $cache_key, $cache_group );
  7394. if ( $cached_sticky_posts ) {
  7395. return $cached_sticky_posts;
  7396. }
  7397. $new_posts = array();
  7398. $posts = array_filter( $posts, create_function( '$a', 'return $a > 0;' ) );
  7399. if(count($posts)==1) {
  7400. $option_sticky_posts_trids_prepared = $wpdb->prepare( "SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id = %d AND element_type='post_post'", array($posts[0]) );
  7401. } else {
  7402. $option_sticky_posts_trids_prepared = "SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id IN (" . join( ',', $posts ) . ") AND element_type='post_post'";
  7403. }
  7404. $trids = $wpdb->get_col( $option_sticky_posts_trids_prepared );
  7405. if ( $trids ) {
  7406. if ( count( $trids ) == 1 ) {
  7407. $option_sticky_posts_prepared = $wpdb->prepare( "SELECT trid, element_id, language_code FROM {$wpdb->prefix}icl_translations WHERE trid = %d AND element_type='post_post'", array( $trids[ 0 ] ) );
  7408. } else {
  7409. $option_sticky_posts_prepared = "SELECT trid, element_id, language_code FROM {$wpdb->prefix}icl_translations WHERE trid IN (" . join( ',', $trids ) . ") AND element_type='post_post'";
  7410. }
  7411. $option_sticky_posts = $wpdb->get_results( $option_sticky_posts_prepared );
  7412. foreach ( $option_sticky_posts as $option_sticky_post ) {
  7413. if ( $option_sticky_post->language_code == $this->this_lang ) {
  7414. if ( !in_array( $option_sticky_post->element_id, $new_posts ) ) {
  7415. $new_posts[ ] = $option_sticky_post->element_id;
  7416. }
  7417. }
  7418. }
  7419. wp_cache_set( $cache_key, $new_posts, $cache_group );
  7420. }
  7421. return $new_posts;
  7422. }
  7423. return $posts;
  7424. }
  7425. function request_filter( $request )
  7426. {
  7427. if ( !defined( 'WP_ADMIN' ) && $this->settings[ 'language_negotiation_type' ] == 3 && isset( $request[ 'lang' ] ) ) {
  7428. // Count the parameters that have settings and remove our 'lang ' setting it's the only one.
  7429. // This is required so that home page detection works for other languages.
  7430. $count = 0;
  7431. foreach ( $request as $data ) {
  7432. if ( $data !== '' ) {
  7433. $count += 1;
  7434. }
  7435. }
  7436. if ( $count == 1 ) {
  7437. unset( $request[ 'lang' ] );
  7438. }
  7439. }
  7440. return $request;
  7441. }
  7442. function noscript_notice()
  7443. {
  7444. ?>
  7445. <noscript>
  7446. <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
  7447. }
  7448. function filter_queries( $sql )
  7449. {
  7450. global $wpdb, $pagenow;
  7451. // keep a record of the queries
  7452. $this->queries[ ] = $sql;
  7453. $current_language = $this->get_current_language();
  7454. if ( $pagenow == 'categories.php' || $pagenow == 'edit-tags.php' ) {
  7455. if ( preg_match( '#^SELECT COUNT\(\*\) FROM ' . $wpdb->term_taxonomy . ' WHERE taxonomy = \'(category|post_tag)\' $#', $sql, $matches ) ) {
  7456. $element_type = 'tax_' . $matches[ 1 ];
  7457. $sql = "
  7458. SELECT COUNT(*) FROM {$wpdb->term_taxonomy} tx
  7459. JOIN {$wpdb->prefix}icl_translations tr ON tx.term_taxonomy_id=tr.element_id
  7460. WHERE tx.taxonomy='{$matches[1]}' AND tr.element_type='{$element_type}' AND tr.language_code='" . $current_language . "'";
  7461. }
  7462. }
  7463. if ( $pagenow == 'edit.php' || $pagenow == 'edit-pages.php' ) {
  7464. $post_type = isset( $_GET[ 'post_type' ] ) ? $_GET[ 'post_type' ] : 'post';
  7465. $element_type = 'post_' . $post_type;
  7466. if ( $this->is_translated_post_type( $post_type ) ) {
  7467. if ( preg_match( '#SELECT post_status, COUNT\( \* \) AS num_posts FROM ' . $wpdb->posts . ' WHERE post_type = \'(.+)\' GROUP BY post_status#i', $sql, $matches ) ) {
  7468. if ( 'all' != $current_language ) {
  7469. $sql = '
  7470. SELECT post_status, COUNT( * ) AS num_posts
  7471. FROM ' . $wpdb->posts . ' p
  7472. JOIN ' . $wpdb->prefix . 'icl_translations t ON p.ID = t.element_id
  7473. WHERE p.post_type = \'' . $matches[ 1 ] . '\'
  7474. AND t.element_type=\'' . $element_type . '\'
  7475. AND t.language_code=\'' . $current_language . '\'
  7476. GROUP BY post_status';
  7477. } else {
  7478. $sql = '
  7479. SELECT post_status, COUNT( * ) AS num_posts
  7480. FROM ' . $wpdb->posts . ' p
  7481. JOIN ' . $wpdb->prefix . 'icl_translations t ON p.ID = t.element_id
  7482. JOIN ' . $wpdb->prefix . 'icl_languages l ON t.language_code = l.code AND l.active = 1
  7483. WHERE p.post_type = \'' . $matches[ 1 ] . '\'
  7484. AND t.element_type=\'' . $element_type . '\'
  7485. GROUP BY post_status';
  7486. }
  7487. }
  7488. }
  7489. }
  7490. if ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'ajax-tag-search' ) {
  7491. $search = 'SELECT t.name FROM ' . $wpdb->term_taxonomy . ' AS tt INNER JOIN ' . $wpdb->terms . ' AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = \'' . esc_sql( $_GET[ 'tax' ] ) . '\' AND t.name LIKE (\'%' . esc_sql( $_GET[ 'q' ] ) . '%\')';
  7492. if ( $sql == $search ) {
  7493. $parts = parse_url( $_SERVER[ 'HTTP_REFERER' ] );
  7494. @parse_str( $parts[ 'query' ], $query );
  7495. $lang = isset( $query[ 'lang' ] ) ? $query[ 'lang' ] : $this->get_language_cookie();
  7496. $element_type = 'tax_' . $_GET[ 'tax' ];
  7497. $sql = 'SELECT t.name FROM ' . $wpdb->term_taxonomy . ' AS tt
  7498. INNER JOIN ' . $wpdb->terms . ' AS t ON tt.term_id = t.term_id
  7499. JOIN ' . $wpdb->prefix . 'icl_translations tr ON tt.term_taxonomy_id = tr.element_id
  7500. WHERE tt.taxonomy = \'' . esc_sql( $_GET[ 'tax' ] ) . '\' AND tr.language_code=\'' . $lang . '\' AND element_type=\'' . $element_type . '\'
  7501. AND t.name LIKE (\'%' . esc_sql( $_GET[ 'q' ] ) . '%\')
  7502. ';
  7503. }
  7504. }
  7505. // filter get page by path WP 3.9+
  7506. if ( version_compare( $GLOBALS[ 'wp_version' ], '3.9', '>=' ) ) {
  7507. if ( preg_match( "#\n\t\tSELECT ID, post_name, post_parent, post_type\n\t\tFROM {$wpdb->posts}\n\t\tWHERE post_name IN \(([^)]+)\)\n\t\tAND post_type IN \(([^)]+)\)#", $sql, $matches ) ) {
  7508. //add 'post_' at the beginning of each post type
  7509. $post_types = explode( ',', str_replace('\'', '', $matches[2]) );
  7510. $element_types = array();
  7511. foreach ($post_types as $post_type){
  7512. $element_types[] = "'post_".$post_type."'";
  7513. }
  7514. $element_types = implode(',', $element_types);
  7515. $sql = "SELECT p.ID, p.post_name, p.post_parent, post_type
  7516. FROM {$wpdb->posts} p
  7517. LEFT JOIN {$wpdb->prefix}icl_translations t on t.element_id = p.ID AND t.element_type IN ({$element_types}) AND t.language_code='" . $current_language . "'
  7518. WHERE p.post_name IN ({$matches[1]}) AND p.post_type IN ({$matches[2]})
  7519. ORDER BY t.language_code='" . $current_language . "' DESC
  7520. ";
  7521. // added order by to ensure that we get the result in teh current language first
  7522. }
  7523. }elseif( version_compare( $GLOBALS[ 'wp_version' ], '3.5', '>=' ) ){
  7524. if ( preg_match( "#SELECT ID, post_name, post_parent, post_type FROM {$wpdb->posts} WHERE post_name IN \(([^)]+)\) AND \(post_type = '([^']+)' OR post_type = 'attachment'\)#", $sql, $matches ) ) {
  7525. $sql = "SELECT p.ID, p.post_name, p.post_parent, post_type
  7526. FROM {$wpdb->posts} p
  7527. LEFT JOIN {$wpdb->prefix}icl_translations t on t.element_id = p.ID AND t.element_type = 'post_{$matches[2]}' AND t.language_code='" . $current_language . "'
  7528. WHERE p.post_name IN ({$matches[1]}) AND (p.post_type = '{$matches[2]}' OR p.post_type = 'attachment')
  7529. ORDER BY t.language_code='" . $current_language . "' DESC
  7530. ";
  7531. // added order by to ensure that we get the result in teh current language first
  7532. }
  7533. } else {
  7534. // filter get page by path WP 3.3+
  7535. 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 ) ) {
  7536. $sql = "SELECT p.ID, p.post_name, p.post_parent
  7537. FROM {$wpdb->posts} p
  7538. LEFT JOIN {$wpdb->prefix}icl_translations t on t.element_id = p.ID AND t.element_type = 'post_{$matches[2]}' AND t.language_code='" . $current_language . "'
  7539. WHERE p.post_name IN ({$matches[1]}) AND (p.post_type = '{$matches[2]}' OR p.post_type = 'attachment')
  7540. ORDER BY t.language_code='" . $current_language . "' DESC
  7541. ";
  7542. // added order by to ensure that we get the result in teh current language first
  7543. } // filter get page by path < WP 3.3
  7544. elseif ( preg_match( "#SELECT ID, post_name, post_parent FROM {$wpdb->posts} WHERE post_name = '([^']+)' AND \(post_type = '([^']+)' OR post_type = 'attachment'\)#", $sql, $matches ) ) {
  7545. $sql = "SELECT p.ID, p.post_name, p.post_parent
  7546. FROM {$wpdb->posts} p
  7547. JOIN {$wpdb->prefix}icl_translations t on t.element_id = p.ID AND t.element_type = 'post_{$matches[2]}'
  7548. WHERE p.post_name = '{$matches[1]}' AND (p.post_type = '{$matches[2]}' OR p.post_type = 'attachment')
  7549. AND t.language_code='" . $current_language . "'";
  7550. }
  7551. }
  7552. // filter calendar widget queries
  7553. //elseif( preg_match("##", $sql, $matches) ){
  7554. //
  7555. //}
  7556. return $sql;
  7557. }
  7558. function get_inactive_content()
  7559. {
  7560. global $wpdb;
  7561. $inactive = array();
  7562. $current_language = $this->get_current_language();
  7563. $res_p_prepared = $wpdb->prepare( "
  7564. SELECT COUNT(p.ID) AS c, p.post_type, lt.name AS language FROM {$wpdb->prefix}icl_translations t
  7565. JOIN {$wpdb->posts} p ON t.element_id=p.ID AND t.element_type LIKE %s
  7566. JOIN {$wpdb->prefix}icl_languages l ON t.language_code = l.code AND l.active = 0
  7567. JOIN {$wpdb->prefix}icl_languages_translations lt ON lt.language_code = l.code AND lt.display_language_code=%s
  7568. GROUP BY p.post_type, t.language_code
  7569. ", array( wpml_like_escape('post_') . '%', $current_language) );
  7570. $res_p = $wpdb->get_results( $res_p_prepared );
  7571. if ($res_p) {
  7572. foreach ( $res_p as $r ) {
  7573. $inactive[ $r->language ][ $r->post_type ] = $r->c;
  7574. }
  7575. }
  7576. $res_t_query = "
  7577. SELECT COUNT(p.term_taxonomy_id) AS c, p.taxonomy, lt.name AS language FROM {$wpdb->prefix}icl_translations t
  7578. JOIN {$wpdb->term_taxonomy} p ON t.element_id=p.term_taxonomy_id
  7579. JOIN {$wpdb->prefix}icl_languages l ON t.language_code = l.code AND l.active = 0
  7580. JOIN {$wpdb->prefix}icl_languages_translations lt ON lt.language_code = l.code AND lt.display_language_code=%s
  7581. WHERE t.element_type LIKE %s
  7582. GROUP BY p.taxonomy, t.language_code
  7583. ";
  7584. $res_t_query_prepared = $wpdb->prepare($res_t_query, $current_language, wpml_like_escape('tax_') . '%');
  7585. $res_t = $wpdb->get_results( $res_t_query_prepared );
  7586. if ($res_t) {
  7587. foreach ( $res_t as $r ) {
  7588. if ( $r->taxonomy == 'category' && $r->c == 1 ) {
  7589. continue; //ignore the case of just the default category that gets automatically created for a new language
  7590. }
  7591. $inactive[ $r->language ][ $r->taxonomy ] = $r->c;
  7592. }
  7593. }
  7594. return $inactive;
  7595. }
  7596. function menu_footer()
  7597. {
  7598. include ICL_PLUGIN_PATH . '/menu/menu-footer.php';
  7599. }
  7600. function _allow_calling_template_file_directly()
  7601. {
  7602. if ( is_404() ) {
  7603. global $wp_query;
  7604. $parts = parse_url( get_bloginfo( 'url' ) );
  7605. if ( !isset( $parts[ 'path' ] ) )
  7606. $parts[ 'path' ] = '';
  7607. $req = str_replace( $parts[ 'path' ], '', $_SERVER[ 'REQUEST_URI' ] );
  7608. $whitelisted_extensions = array('php'=> 1);
  7609. if ( file_exists( ABSPATH . $req ) && !is_dir( ABSPATH . $req ) && isset( $whitelisted_extensions[ pathinfo($req, PATHINFO_EXTENSION) ] ) ) {
  7610. $wp_query->is_404 = false;
  7611. header( 'HTTP/1.1 200 OK' );
  7612. include ABSPATH . $req;
  7613. exit;
  7614. }
  7615. }
  7616. }
  7617. function show_user_options()
  7618. {
  7619. global $current_user;
  7620. $active_languages = $this->get_active_languages();
  7621. $default_language = $this->get_default_language();
  7622. $user_language = get_user_meta( $current_user->data->ID, 'icl_admin_language', true );
  7623. if ( $this->settings[ 'admin_default_language' ] == '_default_' ) {
  7624. $this->settings[ 'admin_default_language' ] = $default_language;
  7625. }
  7626. $lang_details = $this->get_language_details( $this->settings[ 'admin_default_language' ] );
  7627. $admin_default_language = $lang_details[ 'display_name' ];
  7628. ?>
  7629. <a name="wpml"></a>
  7630. <h3><?php _e( 'WPML language settings', 'sitepress' ); ?></h3>
  7631. <table class="form-table">
  7632. <tbody>
  7633. <tr>
  7634. <th><?php _e( 'Select your language:', 'sitepress' ) ?></th>
  7635. <td>
  7636. <select name="icl_user_admin_language">
  7637. <option value=""<?php if ( $user_language == $this->settings[ 'admin_default_language' ] )
  7638. echo ' selected="selected"' ?>><?php printf( __( 'Default admin language (currently %s)', 'sitepress' ), $admin_default_language ); ?>&nbsp;</option>
  7639. <?php foreach ( $active_languages as $al ): ?>
  7640. <option value="<?php echo $al[ 'code' ] ?>"<?php if ( $user_language == $al[ 'code' ] )
  7641. echo ' selected="selected"' ?>><?php echo $al[ 'display_name' ];
  7642. if ( $this->admin_language != $al[ 'code' ] )
  7643. echo ' (' . $al[ 'native_name' ] . ')'; ?>&nbsp;</option>
  7644. <?php endforeach; ?>
  7645. </select>
  7646. <span class="description"><?php _e( 'this will be your admin language and will also be used for translating comments.', 'sitepress' ); ?></span>
  7647. <br/>
  7648. <label><input type="checkbox" name="icl_admin_language_for_edit" value="1"
  7649. <?php if (get_user_meta( $this->get_current_user()->ID, 'icl_admin_language_for_edit', true )): ?>checked="checked"<?php endif; ?> />&nbsp;<?php _e( 'Set admin language as editing language.', 'sitepress' ); ?>
  7650. </label>
  7651. </td>
  7652. </tr>
  7653. <?php //display "hidden languages block" only if user can "manage_options"
  7654. if ( current_user_can( 'manage_options' ) || current_user_can('translate') ): ?>
  7655. <tr>
  7656. <th><?php _e( 'Hidden languages:', 'sitepress' ) ?></th>
  7657. <td>
  7658. <p>
  7659. <?php if ( !empty( $this->settings[ 'hidden_languages' ] ) ): ?>
  7660. <?php
  7661. if ( 1 == count( $this->settings[ 'hidden_languages' ] ) ) {
  7662. printf( __( '%s is currently hidden to visitors.', 'sitepress' ), $active_languages[ $this->settings[ 'hidden_languages' ][ 0 ] ][ 'display_name' ] );
  7663. } else {
  7664. $hidden_languages_array = array();
  7665. foreach ( $this->settings[ 'hidden_languages' ] as $l ) {
  7666. $hidden_languages_array[ ] = $active_languages[ $l ][ 'display_name' ];
  7667. }
  7668. $hidden_languages = join( ', ', $hidden_languages_array );
  7669. printf( __( '%s are currently hidden to visitors.', 'sitepress' ), $hidden_languages );
  7670. }
  7671. ?>
  7672. <?php else: ?>
  7673. <?php _e( 'All languages are currently displayed. Choose what to do when site languages are hidden.', 'sitepress' ); ?>
  7674. <?php endif; ?>
  7675. </p>
  7676. <p>
  7677. <label><input name="icl_show_hidden_languages" type="checkbox" value="1" <?php
  7678. if (get_user_meta( $current_user->data->ID, 'icl_show_hidden_languages', true )):?>checked="checked"<?php endif ?> />&nbsp;<?php
  7679. _e( 'Display hidden languages', 'sitepress' ) ?></label>
  7680. </p>
  7681. </td>
  7682. </tr>
  7683. <?php endif; ?>
  7684. </tbody>
  7685. </table>
  7686. <?php
  7687. }
  7688. function save_user_options()
  7689. {
  7690. $user_id = $_POST[ 'user_id' ];
  7691. if ( $user_id ) {
  7692. update_user_meta( $user_id, 'icl_admin_language', $_POST[ 'icl_user_admin_language' ] );
  7693. update_user_meta( $user_id, 'icl_show_hidden_languages', isset( $_POST[ 'icl_show_hidden_languages' ] ) ? intval( $_POST[ 'icl_show_hidden_languages' ] ) : 0 );
  7694. update_user_meta( $user_id, 'icl_admin_language_for_edit', isset( $_POST[ 'icl_admin_language_for_edit' ] ) ? intval( $_POST[ 'icl_admin_language_for_edit' ] ) : 0 );
  7695. $this->reset_admin_language_cookie();
  7696. $this->icl_locale_cache->clear();
  7697. }
  7698. }
  7699. function help_admin_notice()
  7700. {
  7701. $args = array(
  7702. 'name' => 'wpml-intro',
  7703. 'iso' => defined( 'WPLANG' ) ? WPLANG : '',
  7704. 'src' => get_home_url()
  7705. );
  7706. $q = http_build_query( $args );
  7707. ?>
  7708. <br clear="all"/>
  7709. <div id="message" class="updated message fade" style="clear:both;margin-top:5px;"><p>
  7710. <?php _e( 'WPML is a powerful plugin with many features. Would you like to see a quick overview?', 'sitepress' ); ?>
  7711. </p>
  7712. <p>
  7713. <a href="<?php echo ICL_API_ENDPOINT ?>/destinations/go?<?php echo $q ?>" target="_blank" class="button-primary"><?php _e( 'Yes', 'sitepress' ) ?></a>&nbsp;
  7714. <input type="hidden" id="icl_dismiss_help_nonce" value="<?php echo $icl_dhn = wp_create_nonce( 'dismiss_help_nonce' ) ?>"/>
  7715. <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;
  7716. <a title="<?php _e( 'Stop showing this message', 'sitepress' ) ?>" id="icl_dismiss_help" href=""><?php _e( 'Dismiss', 'sitepress' ) ?></a>
  7717. </p>
  7718. </div>
  7719. <?php
  7720. }
  7721. function upgrade_notice()
  7722. {
  7723. include ICL_PLUGIN_PATH . '/menu/upgrade_notice.php';
  7724. }
  7725. function icl_reminders()
  7726. {
  7727. include ICL_PLUGIN_PATH . '/menu/icl_reminders.php';
  7728. }
  7729. function add_posts_management_column( $columns )
  7730. {
  7731. global $posts, $wpdb, $__management_columns_posts_translations;
  7732. $element_type = isset( $_REQUEST[ 'post_type' ] ) ? 'post_' . $_REQUEST[ 'post_type' ] : 'post_post';
  7733. if ( count( $this->get_active_languages() ) <= 1 || get_query_var( 'post_status' ) == 'trash' ) {
  7734. return $columns;
  7735. }
  7736. if ( isset( $_POST[ 'action' ] ) && $_POST[ 'action' ] == 'inline-save' && $_POST[ 'post_ID' ] ) {
  7737. $p = new stdClass();
  7738. $p->ID = $_POST[ 'post_ID' ];
  7739. $posts = array( $p );
  7740. } elseif ( empty( $posts ) ) {
  7741. return $columns;
  7742. }
  7743. if ( is_null( $__management_columns_posts_translations ) ) {
  7744. $post_ids = array();
  7745. foreach ( $posts as $p ) {
  7746. $post_ids[ ] = $p->ID;
  7747. }
  7748. // get posts translations
  7749. // get trids
  7750. $trid_array = $wpdb->get_col( "
  7751. SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_type='{$element_type}' AND element_id IN (" . join( ',', $post_ids ) . ")
  7752. " );
  7753. $elements_translations = $wpdb->get_results( "
  7754. SELECT trid, element_id, language_code, source_language_code FROM {$wpdb->prefix}icl_translations WHERE trid IN (" . join( ',', $trid_array ) . ")
  7755. " );
  7756. foreach ( $elements_translations as $v ) {
  7757. $by_trid[ $v->trid ][ ] = $v;
  7758. }
  7759. foreach ( $elements_translations as $v ) {
  7760. if ( in_array( $v->element_id, $post_ids ) ) {
  7761. $el_trid = $v->trid;
  7762. foreach ( $elements_translations as $val ) {
  7763. if ( $val->trid == $el_trid ) {
  7764. $__management_columns_posts_translations[ $v->element_id ][ $val->language_code ] = $val;
  7765. }
  7766. }
  7767. }
  7768. }
  7769. }
  7770. $active_languages = $this->get_active_languages();
  7771. $languages = array();
  7772. foreach ( $active_languages as $v ) {
  7773. if ( $v[ 'code' ] == $this->get_current_language() )
  7774. continue;
  7775. $languages[ ] = $v[ 'code' ];
  7776. }
  7777. $res = $wpdb->get_results( "
  7778. SELECT f.lang_code, f.flag, f.from_template, l.name
  7779. FROM {$wpdb->prefix}icl_flags f
  7780. JOIN {$wpdb->prefix}icl_languages_translations l ON f.lang_code = l.language_code
  7781. WHERE l.display_language_code = '" . $this->admin_language . "' AND f.lang_code IN('" . join( "','", $languages ) . "')
  7782. " );
  7783. foreach ( $res as $r ) {
  7784. if ( $r->from_template ) {
  7785. $wp_upload_dir = wp_upload_dir();
  7786. $flag_path = $wp_upload_dir[ 'baseurl' ] . '/flags/';
  7787. } else {
  7788. $flag_path = ICL_PLUGIN_URL . '/res/flags/';
  7789. }
  7790. $flags[ $r->lang_code ] = '<img src="' . $flag_path . $r->flag . '" width="18" height="12" alt="' . $r->name . '" title="' . $r->name . '" />';
  7791. }
  7792. $flags_column = '';
  7793. foreach ( $active_languages as $v ) {
  7794. if ( isset( $flags[ $v[ 'code' ] ] ) )
  7795. $flags_column .= $flags[ $v[ 'code' ] ];
  7796. }
  7797. $new_columns = array();
  7798. foreach ( $columns as $k => $v ) {
  7799. $new_columns[ $k ] = $v;
  7800. if ( $k == 'title' ) {
  7801. $new_columns[ 'icl_translations' ] = $flags_column;
  7802. }
  7803. }
  7804. return $new_columns;
  7805. }
  7806. function add_content_for_posts_management_column( $column_name )
  7807. {
  7808. if ( $column_name != 'icl_translations' )
  7809. return;
  7810. global $wpdb, $id, $__management_columns_posts_translations, $sitepress, $iclTranslationManagement;
  7811. $active_languages = $this->get_active_languages();
  7812. $current_language = $this->get_current_language();
  7813. foreach ( $active_languages as $v ) {
  7814. if ( $v[ 'code' ] == $current_language )
  7815. continue;
  7816. $post_type = isset( $_REQUEST[ 'post_type' ] ) ? $_REQUEST[ 'post_type' ] : 'post';
  7817. if ( isset( $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ] ) && $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ]->element_id ) {
  7818. // Translation exists
  7819. $exist_translation = true;
  7820. $trid = $this->get_element_trid( $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ]->element_id, 'post_' . $post_type );
  7821. $source_language_code = $wpdb->get_var( $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND source_language_code IS NULL", $trid ) );
  7822. $needs_update = $wpdb->get_var( $wpdb->prepare( "
  7823. SELECT needs_update
  7824. FROM {$wpdb->prefix}icl_translation_status s JOIN {$wpdb->prefix}icl_translations t ON t.translation_id = s.translation_id
  7825. WHERE t.trid = %d AND t.language_code = '%s'
  7826. ", $trid, $v[ 'code' ] ) );
  7827. if ( $needs_update ) {
  7828. $img = 'needs-update.png';
  7829. $alt = sprintf( __( 'Update %s translation', 'sitepress' ), $v[ 'display_name' ] );
  7830. } else {
  7831. $img = 'edit_translation.png';
  7832. $alt = sprintf( __( 'Edit the %s translation', 'sitepress' ), $v[ 'display_name' ] );
  7833. }
  7834. switch ( $iclTranslationManagement->settings[ 'doc_translation_method' ] ) {
  7835. case ICL_TM_TMETHOD_EDITOR:
  7836. $job_id = $iclTranslationManagement->get_translation_job_id( $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ]->trid, $v[ 'code' ] );
  7837. $args = array( 'lang_from' => $current_language, 'lang_to' => $v[ 'code' ], 'job_id' => @intval( $job_id ) );
  7838. // is a translator of this document?
  7839. $current_user_is_translator = $iclTranslationManagement->is_translator( $this->get_current_user()->ID, $args );
  7840. if ( !$current_user_is_translator ) {
  7841. $img = 'edit_translation_disabled.png';
  7842. $link = '#';
  7843. // is a translator of this language?
  7844. unset( $args[ 'job_id' ] );
  7845. $current_user_is_translator = $iclTranslationManagement->is_translator( $this->get_current_user()->ID, $args );
  7846. if ( $current_user_is_translator ) {
  7847. $alt = sprintf( __( "You can't edit this translation because you're not the translator. <a%s>Learn more.</a>", 'sitepress' ), ' href="https://wpml.org/?page_id=52218"' );
  7848. } else {
  7849. $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="https://wpml.org/?page_id=52218"' );
  7850. }
  7851. } elseif ( $v[ 'code' ] == $source_language_code ) {
  7852. $img = 'edit_translation_disabled.png';
  7853. $link = '#';
  7854. $alt = __( "You can't edit the original document using the translation editor", 'sitepress' );
  7855. } else {
  7856. if ( $job_id ) {
  7857. $link = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&job_id=' . $job_id . '&lang=' . $v[ 'code' ] );
  7858. } else {
  7859. $link = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&icl_tm_action=create_job&iclpost[]=' . $id . '&translate_to[' . $v[ 'code' ] . ']=1&iclnonce=' . wp_create_nonce( 'pro-translation-icl' ) . '&lang=' . $v[ 'code' ] );
  7860. }
  7861. }
  7862. break;
  7863. case ICL_TM_TMETHOD_PRO:
  7864. if ( !$__management_columns_posts_translations[ $id ][ $v[ 'code' ] ]->source_language_code ) {
  7865. $link = get_edit_post_link( $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ]->element_id );
  7866. $alt = __( 'Edit the original document', 'sitepress' );
  7867. } else {
  7868. $job_id = $iclTranslationManagement->get_translation_job_id( $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ]->trid, $v[ 'code' ] );
  7869. if ( $job_id ) {
  7870. $job_details = $iclTranslationManagement->get_translation_job( $job_id );
  7871. if ( $job_details->status == ICL_TM_IN_PROGRESS || $job_details->status == ICL_TM_WAITING_FOR_TRANSLATOR ) {
  7872. $img = 'in-progress.png';
  7873. $alt = sprintf( __( 'Translation to %s is in progress', 'sitepress' ), $v[ 'display_name' ] );
  7874. $link = false;
  7875. echo '<img style="padding:1px;margin:2px;" border="0" src="' . ICL_PLUGIN_URL . '/res/img/' . $img . '" title="' . $alt . '" alt="' . $alt . '" width="16" height="16" />';
  7876. } else {
  7877. $link = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&job_id=' . $job_id );
  7878. }
  7879. }
  7880. }
  7881. break;
  7882. default:
  7883. $link = 'post.php?post_type=' . $post_type . '&action=edit&amp;post=' . $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ]->element_id . '&amp;lang=' . $v[ 'code' ];
  7884. }
  7885. } else {
  7886. // Translation does not exist
  7887. $exist_translation = false;
  7888. $img = 'add_translation.png';
  7889. $alt = sprintf( __( 'Add translation to %s', 'sitepress' ), $v[ 'display_name' ] );
  7890. $default_language = $this->get_default_language();
  7891. $src_lang = $current_language;
  7892. if($src_lang == 'all') {
  7893. $trid = $sitepress->get_element_trid($id, 'post_' . $post_type);
  7894. $element_translations = $sitepress->get_element_translations($trid, 'post_' . $post_type);
  7895. foreach($element_translations as $element_translation) {
  7896. if($element_translation->original) {
  7897. $src_lang = $element_translation->language_code;
  7898. break;
  7899. }
  7900. }
  7901. }
  7902. switch ( $iclTranslationManagement->settings[ 'doc_translation_method' ] ) {
  7903. case ICL_TM_TMETHOD_EDITOR:
  7904. if ( isset( $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ] ) ) {
  7905. $job_id = $iclTranslationManagement->get_translation_job_id( $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ]->trid, $v[ 'code' ] );
  7906. } else {
  7907. $job_id = 0;
  7908. }
  7909. $args = array( 'lang_from' => $src_lang, 'lang_to' => $v[ 'code' ], 'job_id' => @intval( $job_id ) );
  7910. $current_user_is_translator = $iclTranslationManagement->is_translator( $this->get_current_user()->ID, $args );
  7911. if ( $job_id ) {
  7912. if ( $current_user_is_translator ) {
  7913. $job_details = $iclTranslationManagement->get_translation_job( $job_id );
  7914. if ( $job_details && $job_details->status == ICL_TM_IN_PROGRESS ) {
  7915. $img = 'in-progress.png';
  7916. $alt = sprintf( __( 'Translation to %s is in progress', 'sitepress' ), $v[ 'display_name' ] );
  7917. }
  7918. $link = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&job_id=' . $job_id . '&lang=' . $v[ 'code' ] );
  7919. } else {
  7920. $link = '#';
  7921. $tres = $wpdb->get_row( $wpdb->prepare( "
  7922. SELECT s.* FROM {$wpdb->prefix}icl_translation_status s
  7923. JOIN {$wpdb->prefix}icl_translate_job j ON j.rid = s.rid
  7924. WHERE job_id=%d
  7925. ", $job_id ) );
  7926. if ( $tres->status == ICL_TM_IN_PROGRESS ) {
  7927. $img = 'in-progress.png';
  7928. $alt = sprintf( __( 'Translation to %s is in progress (by a different translator)', 'sitepress' ), $v[ 'display_name' ] );
  7929. } elseif ( $tres->status == ICL_TM_NOT_TRANSLATED || $tres->status == ICL_TM_WAITING_FOR_TRANSLATOR ) {
  7930. $img = 'add_translation_disabled.png';
  7931. $alt = sprintf( __( 'Translation to %s is in progress (by a different translator)', 'sitepress' ), $v[ 'display_name' ] );
  7932. } elseif ( $tres->status == ICL_TM_NEEDS_UPDATE || $tres->status == ICL_TM_COMPLETE ) {
  7933. $img = 'edit_translation_disabled.png';
  7934. $alt = sprintf( __( 'Translation to %s is maintained by a different translator', 'sitepress' ), $v[ 'display_name' ] );
  7935. }
  7936. }
  7937. } else {
  7938. if ( $current_user_is_translator ) {
  7939. $link = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&icl_tm_action=create_job&iclpost[]=' . $id . '&translate_to[' . $v[ 'code' ] . ']=1&iclnonce=' . wp_create_nonce( 'pro-translation-icl' ) );
  7940. if ( $current_language != $default_language ) {
  7941. $link .= '&translate_from=' . $current_language;
  7942. }
  7943. } else {
  7944. $link = '#';
  7945. $img = 'add_translation_disabled.png';
  7946. $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="https://wpml.org/?page_id=52218"' );
  7947. }
  7948. }
  7949. break;
  7950. case ICL_TM_TMETHOD_PRO:
  7951. if ( $this->have_icl_translator( $src_lang, $v[ 'code' ] ) ) {
  7952. if ( !isset( $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ] ) )
  7953. $job_id = false; else
  7954. $job_id = @$iclTranslationManagement->get_translation_job_id( $__management_columns_posts_translations[ $id ][ $v[ 'code' ] ]->trid, $v[ 'code' ] );
  7955. if ( $job_id ) {
  7956. $job_details = $iclTranslationManagement->get_translation_job( $job_id );
  7957. if ( $job_details->status == ICL_TM_IN_PROGRESS || $job_details->status == ICL_TM_WAITING_FOR_TRANSLATOR ) {
  7958. $img = 'in-progress.png';
  7959. $alt = sprintf( __( 'Translation to %s is in progress', 'sitepress' ), $v[ 'display_name' ] );
  7960. $link = false;
  7961. echo '<img style="padding:1px;margin:2px;" border="0" src="' . ICL_PLUGIN_URL . '/res/img/' . $img . '" title="' . $alt . '" alt="' . $alt . '" width="16" height="16" />';
  7962. } else {
  7963. $link = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&job_id=' . $job_id );
  7964. }
  7965. } else {
  7966. $qs = array();
  7967. if ( !empty( $_SERVER[ 'QUERY_STRING' ] ) )
  7968. foreach ( $_exp = explode( '&', $_SERVER[ 'QUERY_STRING' ] ) as $q => $qv ) {
  7969. $__exp = explode( '=', $qv );
  7970. $__exp[ 0 ] = preg_replace( '#\[(.*)\]#', '', $__exp[ 0 ] );
  7971. if ( !in_array( $__exp[ 0 ], array( 'icl_tm_action', 'translate_from', 'translate_to', 'iclpost', 'service', 'iclnonce' ) ) ) {
  7972. $qs[ $q ] = $qv;
  7973. }
  7974. }
  7975. $link = admin_url( 'edit.php?' . join( '&', $qs ) . '&icl_tm_action=send_jobs&translate_from=' . $src_lang . '&translate_to[' . $v[ 'code' ] . ']=1&iclpost[]=' . $id . '&service=icanlocalize&iclnonce=' . wp_create_nonce( 'pro-translation-icl' ) );
  7976. }
  7977. } else {
  7978. $link = false;
  7979. $alt = sprintf( __( 'Get %s translators', 'sitepress' ), $v[ 'display_name' ] );
  7980. $img = 'add_translators.png';
  7981. echo $this->create_icl_popup_link( "@select-translators;{$src_lang};{$v['code']}@", array(
  7982. 'ar' => 1, 'title' => $alt, 'unload_cb' => 'icl_pt_reload_translation_box'
  7983. ) ) . '<img style="padding:1px;margin:2px;" border="0" src="' . ICL_PLUGIN_URL . '/res/img/' . $img . '" alt="' . $alt . '" width="16" height="16" />' . '</a>';
  7984. }
  7985. break;
  7986. default:
  7987. global $sitepress;
  7988. $trid = $sitepress->get_element_trid( $id, 'post_' . $post_type );
  7989. $link = 'post-new.php?post_type=' . $post_type . '&trid=' . $trid . '&amp;lang=' . $v[ 'code' ] . '&amp;source_lang=' . $src_lang;
  7990. }
  7991. }
  7992. if ( isset($link) && $link ) {
  7993. if ( $link == '#' ) {
  7994. icl_pop_info( $alt, ICL_PLUGIN_URL . '/res/img/' . $img, array( 'icon_size' => 16, 'but_style' => array( 'icl_pop_info_but_noabs' ) ) );
  7995. } else {
  7996. $link = apply_filters( 'wpml_link_to_translation', $link, $exist_translation, $v[ 'code' ] );
  7997. echo '<a href="' . $link . '" title="' . $alt . '">';
  7998. echo '<img style="padding:1px;margin:2px;" border="0" src="' . ICL_PLUGIN_URL . '/res/img/' . $img . '" alt="' . $alt . '" width="16" height="16" />';
  7999. echo '</a>';
  8000. }
  8001. }
  8002. }
  8003. }
  8004. function __set_posts_management_column_width()
  8005. {
  8006. $w = 22 * count( $this->get_active_languages() );
  8007. echo '<style type="text/css">.column-icl_translations{width:' . $w . 'px;}.column-icl_translations img{margin:2px;}</style>';
  8008. }
  8009. function display_wpml_footer()
  8010. {
  8011. if ( $this->settings[ 'promote_wpml' ] ) {
  8012. $wpml_in_other_langs = array( 'es', 'de', 'ja', 'zh-hans' );
  8013. $cl = in_array( ICL_LANGUAGE_CODE, $wpml_in_other_langs ) ? ICL_LANGUAGE_CODE . '/' : '';
  8014. $wpml_in_other_langs_icl = array( 'es', 'fr', 'de' );
  8015. $cl_icl = in_array( ICL_LANGUAGE_CODE, $wpml_in_other_langs_icl ) ? ICL_LANGUAGE_CODE . '/' : '';
  8016. $nofollow_wpml = is_home() ? '' : ' rel="nofollow"';
  8017. if ( in_array( ICL_LANGUAGE_CODE, array( 'ja', 'zh-hans', 'zh-hant', 'ko' ) ) ) {
  8018. // parameters order is set according to teh translation
  8019. echo '<p id="wpml_credit_footer">' . sprintf( __( '<a href="%s"%s>Multilingual WordPress</a> by <a href="%s" rel="nofollow">ICanLocalize</a>', 'sitepress' ), 'http://www.icanlocalize.com/site/' . $cl_icl, 'https://wpml.org/' . $cl, $nofollow_wpml ) . '</p>';
  8020. } else {
  8021. echo '<p id="wpml_credit_footer">' . sprintf( __( '<a href="%s"%s>Multilingual WordPress</a> by <a href="%s" rel="nofollow">ICanLocalize</a>', 'sitepress' ), 'https://wpml.org/' . $cl, $nofollow_wpml, 'http://www.icanlocalize.com/site/' . $cl_icl ) . '</p>';
  8022. }
  8023. }
  8024. }
  8025. function xmlrpc_methods( $methods )
  8026. {
  8027. $methods[ 'icanlocalize.get_languages_list' ] = array( $this, 'xmlrpc_get_languages_list' );
  8028. return $methods;
  8029. }
  8030. function xmlrpc_call_actions( $action )
  8031. {
  8032. global $HTTP_RAW_POST_DATA, $wpdb;
  8033. $params = icl_xml2array( $HTTP_RAW_POST_DATA );
  8034. add_filter( 'is_protected_meta', array( $this, 'xml_unprotect_wpml_meta' ), 10, 3 );
  8035. switch ( $action ) {
  8036. case 'wp.getPage':
  8037. case 'blogger.getPost': // yet this doesn't return custom fields
  8038. if ( isset( $params[ 'methodCall' ][ 'params' ][ 'param' ][ 1 ][ 'value' ][ 'int' ][ 'value' ] ) ) {
  8039. $page_id = $params[ 'methodCall' ][ 'params' ][ 'param' ][ 1 ][ 'value' ][ 'int' ][ 'value' ];
  8040. $lang_details = $this->get_element_language_details( $page_id, 'post_' . get_post_type( $page_id ) );
  8041. $this->this_lang = $lang_details->language_code; // set the current language to the posts language
  8042. update_post_meta( $page_id, '_wpml_language', $lang_details->language_code );
  8043. update_post_meta( $page_id, '_wpml_trid', $lang_details->trid );
  8044. $active_languages = $this->get_active_languages();
  8045. $res = $this->get_element_translations( $lang_details->trid );
  8046. $translations = array();
  8047. foreach ( $active_languages as $k => $v ) {
  8048. if ( $page_id != $res[ $k ]->element_id ) {
  8049. $translations[ $k ] = isset( $res[ $k ]->element_id ) ? $res[ $k ]->element_id : 0;
  8050. }
  8051. }
  8052. update_post_meta( $page_id, '_wpml_translations', json_encode( $translations ) );
  8053. }
  8054. break;
  8055. case 'metaWeblog.getPost':
  8056. if ( isset( $params[ 'methodCall' ][ 'params' ][ 'param' ][ 0 ][ 'value' ][ 'int' ][ 'value' ] ) ) {
  8057. $page_id = $params[ 'methodCall' ][ 'params' ][ 'param' ][ 0 ][ 'value' ][ 'int' ][ 'value' ];
  8058. $lang_details = $this->get_element_language_details( $page_id, 'post_' . get_post_type( $page_id ) );
  8059. $this->this_lang = $lang_details->language_code; // set the current language to the posts language
  8060. update_post_meta( $page_id, '_wpml_language', $lang_details->language_code );
  8061. update_post_meta( $page_id, '_wpml_trid', $lang_details->trid );
  8062. $active_languages = $this->get_active_languages();
  8063. $res = $this->get_element_translations( $lang_details->trid );
  8064. $translations = array();
  8065. foreach ( $active_languages as $k => $v ) {
  8066. if ( isset( $res[ $k ] ) && $page_id != $res[ $k ]->element_id ) {
  8067. $translations[ $k ] = isset( $res[ $k ]->element_id ) ? $res[ $k ]->element_id : 0;
  8068. }
  8069. }
  8070. update_post_meta( $page_id, '_wpml_translations', json_encode( $translations ) );
  8071. }
  8072. break;
  8073. case 'metaWeblog.getRecentPosts':
  8074. if ( isset( $params[ 'methodCall' ][ 'params' ][ 'param' ][ 3 ][ 'value' ][ 'int' ][ 'value' ] ) ) {
  8075. $num_posts = intval( $params[ 'methodCall' ][ 'params' ][ 'param' ][ 3 ][ 'value' ][ 'int' ][ 'value' ] );
  8076. if ( $num_posts ) {
  8077. $posts = get_posts( 'suppress_filters=false&numberposts=' . $num_posts );
  8078. foreach ( $posts as $p ) {
  8079. $lang_details = $this->get_element_language_details( $p->ID, 'post_post' );
  8080. update_post_meta( $p->ID, '_wpml_language', $lang_details->language_code );
  8081. update_post_meta( $p->ID, '_wpml_trid', $lang_details->trid );
  8082. $active_languages = $this->get_active_languages();
  8083. $res = $this->get_element_translations( $lang_details->trid );
  8084. $translations = array();
  8085. foreach ( $active_languages as $k => $v ) {
  8086. if ( $p->ID != $res[ $k ]->element_id ) {
  8087. $translations[ $k ] = isset( $res[ $k ]->element_id ) ? $res[ $k ]->element_id : 0;
  8088. }
  8089. }
  8090. update_post_meta( $p->ID, '_wpml_translations', json_encode( $translations ) );
  8091. }
  8092. }
  8093. }
  8094. break;
  8095. case 'metaWeblog.newPost':
  8096. $custom_fields = false;
  8097. if ( is_array( $params[ 'methodCall' ][ 'params' ][ 'param' ][ 3 ][ 'value' ][ 'struct' ][ 'member' ] ) ) {
  8098. foreach ( $params[ 'methodCall' ][ 'params' ][ 'param' ][ 3 ][ 'value' ][ 'struct' ][ 'member' ] as $m ) {
  8099. if ( $m[ 'name' ][ 'value' ] == 'custom_fields' ) {
  8100. $custom_fields_raw = $m[ 'value' ][ 'array' ][ 'data' ][ 'value' ];
  8101. break;
  8102. }
  8103. }
  8104. }
  8105. if ( !empty( $custom_fields_raw ) ) {
  8106. foreach ( $custom_fields_raw as $cf ) {
  8107. $key = $value = null;
  8108. foreach ( $cf[ 'struct' ][ 'member' ] as $m ) {
  8109. if ( $m[ 'name' ][ 'value' ] == 'key' )
  8110. $key = $m[ 'value' ][ 'string' ][ 'value' ]; elseif ( $m[ 'name' ][ 'value' ] == 'value' )
  8111. $value = $m[ 'value' ][ 'string' ][ 'value' ];
  8112. }
  8113. if ( $key !== null && $value !== null )
  8114. $custom_fields[ $key ] = $value;
  8115. }
  8116. }
  8117. if ( is_array( $custom_fields ) && isset( $custom_fields[ '_wpml_language' ] ) && isset( $custom_fields[ '_wpml_trid' ] ) ) {
  8118. $icl_post_language = $custom_fields[ '_wpml_language' ];
  8119. $icl_trid = $custom_fields[ '_wpml_trid' ];
  8120. $post_type = $params[ 'methodCall' ][ 'params' ][ 'param' ][ 3 ][ 'value' ][ 'struct' ][ 'member' ][ 2 ][ 'value' ][ 'string' ][ 'value' ];
  8121. 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}'" ) ) {
  8122. $_POST[ 'icl_post_language' ] = $icl_post_language;
  8123. $_POST[ 'icl_trid' ] = $icl_trid;
  8124. } else {
  8125. $IXR_Error = new IXR_Error( 401, __( 'A translation for this post already exists', 'sitepress' ) );
  8126. echo $IXR_Error->getXml();
  8127. exit( 1 );
  8128. }
  8129. }
  8130. break;
  8131. case 'metaWeblog.editPost':
  8132. $post_id = $params[ 'methodCall' ][ 'params' ][ 'param' ][ 0 ][ 'value' ][ 'int' ][ 'value' ];
  8133. if ( !$post_id ) {
  8134. break;
  8135. }
  8136. $custom_fields = $params[ 'methodCall' ][ 'params' ][ 'param' ][ 3 ][ 'value' ][ 'struct' ][ 'member' ][ 3 ][ 'value' ][ 'array' ][ 'data' ][ 'value' ];
  8137. if ( is_array( $custom_fields ) ) {
  8138. $icl_trid = false;
  8139. $icl_post_language = false;
  8140. foreach ( $custom_fields as $cf ) {
  8141. if ( $cf[ 'struct' ][ 'member' ][ 0 ][ 'value' ][ 'string' ][ 'value' ] == '_wpml_language' ) {
  8142. $icl_post_language = $cf[ 'struct' ][ 'member' ][ 1 ][ 'value' ][ 'string' ][ 'value' ];
  8143. } elseif ( $cf[ 'struct' ][ 'member' ][ 0 ][ 'value' ][ 'string' ][ 'value' ] == '_wpml_trid' ) {
  8144. $icl_trid = $cf[ 'struct' ][ 'member' ][ 1 ][ 'value' ][ 'string' ][ 'value' ];
  8145. }
  8146. }
  8147. $epost_id = $wpdb->get_var( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type='post_post'
  8148. AND trid={$icl_trid} AND language_code='{$icl_post_language}'" );
  8149. if ( $icl_trid && $icl_post_language && ( !$epost_id || $epost_id == $post_id ) ) {
  8150. $_POST[ 'icl_post_language' ] = $icl_post_language;
  8151. $_POST[ 'icl_trid' ] = $icl_trid;
  8152. } else {
  8153. $IXR_Error = new IXR_Error( 401, __( 'A translation in this language already exists', 'sitepress' ) );
  8154. echo $IXR_Error->getXml();
  8155. exit( 1 );
  8156. }
  8157. }
  8158. break;
  8159. }
  8160. }
  8161. function xmlrpc_get_languages_list( $lang )
  8162. {
  8163. global $wpdb;
  8164. if ( !is_null( $lang ) ) {
  8165. if ( !$wpdb->get_var( "SELECT code FROM {$wpdb->prefix}icl_languages WHERE code='" . esc_sql( $lang ) . "'" ) ) {
  8166. $IXR_Error = new IXR_Error( 401, __( 'Invalid language code', 'sitepress' ) );
  8167. echo $IXR_Error->getXml();
  8168. exit( 1 );
  8169. }
  8170. $this->admin_language = $lang;
  8171. }
  8172. define( 'WP_ADMIN', true ); // hack - allow to force display language
  8173. $active_languages = $this->get_active_languages( true );
  8174. return $active_languages;
  8175. }
  8176. function xml_unprotect_wpml_meta( $protected, $meta_key, $meta_type )
  8177. {
  8178. $metas_list = array( '_wpml_trid', '_wpml_translations', '_wpml_language' );
  8179. if ( in_array( $meta_key, $metas_list, true ) ) {
  8180. $protected = false;
  8181. }
  8182. return $protected;
  8183. }
  8184. function get_current_action_step()
  8185. {
  8186. global $wpdb;
  8187. $icl_lang_status = $this->settings[ 'icl_lang_status' ];
  8188. $has_translators = false;
  8189. foreach ( (array)$icl_lang_status as $k => $lang ) {
  8190. if ( !is_numeric( $k ) )
  8191. continue;
  8192. if ( !empty( $lang[ 'translators' ] ) ) {
  8193. $has_translators = true;
  8194. break;
  8195. }
  8196. }
  8197. if ( !$has_translators ) {
  8198. return 0;
  8199. }
  8200. $cms_count = $wpdb->get_var( "SELECT COUNT(rid) FROM {$wpdb->prefix}icl_core_status WHERE status=3" );
  8201. if ( $cms_count > 0 ) {
  8202. return 4;
  8203. }
  8204. $cms_count = $wpdb->get_var( "SELECT COUNT(rid) FROM {$wpdb->prefix}icl_core_status WHERE 1" );
  8205. if ( $cms_count == 0 ) {
  8206. // No documents sent yet
  8207. return 1;
  8208. }
  8209. if ( $this->settings[ 'icl_balance' ] <= 0 ) {
  8210. return 2;
  8211. }
  8212. return 3;
  8213. }
  8214. function show_action_list()
  8215. {
  8216. $steps = array(
  8217. __( 'Select translators', 'sitepress' ), __( 'Send documents to translation', 'sitepress' ), __( 'Deposit payment', 'sitepress' ), __( 'Translations will be returned to your site', 'sitepress' )
  8218. );
  8219. $current_step = $this->get_current_action_step();
  8220. if ( $current_step >= sizeof( $steps ) ) {
  8221. // everything is already setup.
  8222. if ( $this->settings[ 'last_action_step_shown' ] ) {
  8223. return '';
  8224. } else {
  8225. $this->save_settings( array( 'last_action_step_shown' => 1 ) );
  8226. }
  8227. }
  8228. $output = '
  8229. <h3>' . __( 'Setup check list', 'sitepress' ) . '</h3>
  8230. <ul id="icl_check_list">';
  8231. foreach ( $steps as $index => $step ) {
  8232. $step_data = $step;
  8233. if ( $index < $current_step || ( $index == 4 && $this->settings[ 'icl_balance' ] > 0 ) ) {
  8234. $attr = ' class="icl_tick"';
  8235. } else {
  8236. $attr = ' class="icl_next_step"';
  8237. }
  8238. if ( $index == $current_step ) {
  8239. $output .= '<li class="icl_info"><b>' . $step_data . '</b></li>';
  8240. } else {
  8241. $output .= '<li' . $attr . '>' . $step_data . '</li>';
  8242. }
  8243. $output .= "\n";
  8244. }
  8245. $output .= '
  8246. </ul>';
  8247. return $output;
  8248. }
  8249. function show_pro_sidebar()
  8250. {
  8251. $output = '<div id="icl_sidebar" class="icl_sidebar" style="display:none">';
  8252. $action_list = $this->show_action_list();
  8253. $show_minimized = $this->settings[ 'icl_sidebar_minimized' ];
  8254. if ( $action_list != '' ) {
  8255. $show_minimized = false;
  8256. }
  8257. if ( $show_minimized ) {
  8258. $output .= '<div id="icl_sidebar_full" style="display:none">';
  8259. } else {
  8260. $output .= '<div id="icl_sidebar_full">';
  8261. }
  8262. if ( $action_list == '' ) {
  8263. $output .= '<a id="icl_sidebar_hide" href="#">hide</a>';
  8264. } else {
  8265. $output .= $action_list;
  8266. }
  8267. $output .= '<h3>' . __( 'Help', 'sitepress' ) . '</h3>';
  8268. $output .= '<div id="icl_help_links"></div>';
  8269. $output .= wp_nonce_field( 'icl_help_links_nonce', '_icl_nonce_hl', false, false );
  8270. $output .= '</div>';
  8271. if ( $show_minimized ) {
  8272. $output .= '<div id="icl_sidebar_hide_div">';
  8273. } else {
  8274. $output .= '<div id="icl_sidebar_hide_div" style="display:none">';
  8275. }
  8276. $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>';
  8277. $output .= wp_nonce_field( 'icl_show_sidebar_nonce', '_icl_nonce_ss', false, false );
  8278. $output .= '</div>';
  8279. $output .= '</div>';
  8280. return $output;
  8281. }
  8282. function meta_generator_tag()
  8283. {
  8284. $lids = array();
  8285. $active_languages = $this->get_active_languages();
  8286. if($active_languages) {
  8287. foreach ( $active_languages as $l ) {
  8288. $lids[ ] = $l[ 'id' ];
  8289. }
  8290. $stt = join( ",", $lids );
  8291. $stt .= ";" . intval( $this->get_icl_translation_enabled() );
  8292. printf( '<meta name="generator" content="WPML ver:%s stt:%s" />' . PHP_EOL, ICL_SITEPRESS_VERSION, $stt );
  8293. }
  8294. }
  8295. function set_language_cookie()
  8296. {
  8297. if ( !headers_sent() ) {
  8298. if ( preg_match( '@\.(css|js|png|jpg|gif|jpeg|bmp)@i', basename( preg_replace( '@\?.*$@', '', $_SERVER[ 'REQUEST_URI' ] ) ) ) || isset( $_POST[ 'icl_ajx_action' ] ) || isset( $_POST[ '_ajax_nonce' ] ) || defined( 'DOING_AJAX' ) ) {
  8299. return;
  8300. }
  8301. $server_host_name = $this->get_server_host_name();
  8302. $cookie_domain = defined( 'COOKIE_DOMAIN' ) ? COOKIE_DOMAIN : $server_host_name;
  8303. $cookie_path = defined( 'COOKIEPATH' ) ? COOKIEPATH : '/';
  8304. setcookie( '_icl_current_language', $this->get_current_language(), time() + 86400, $cookie_path, $cookie_domain );
  8305. }
  8306. }
  8307. function update_language_cookie($language_code) {
  8308. $_COOKIE[ '_icl_current_language' ] = $language_code;
  8309. }
  8310. function get_language_cookie()
  8311. {
  8312. static $active_languages = false;
  8313. if ( isset( $_COOKIE[ '_icl_current_language' ] ) ) {
  8314. $lang = substr( $_COOKIE[ '_icl_current_language' ], 0, 10 );
  8315. if(!$active_languages) {
  8316. $active_languages = $this->get_active_languages();
  8317. }
  8318. if ( !isset( $active_languages[ $lang ] ) ) {
  8319. $lang = $this->get_default_language();
  8320. }
  8321. } else {
  8322. $lang = '';
  8323. }
  8324. return $lang;
  8325. }
  8326. // _icl_current_language will have to be replaced with _icl_current_language
  8327. function set_admin_language_cookie( $lang = false )
  8328. {
  8329. if ( !headers_sent() ) {
  8330. if ( preg_match( '@\.(css|js|png|jpg|gif|jpeg|bmp)@i', basename( preg_replace( '@\?.*$@', '', $_SERVER[ 'REQUEST_URI' ] ) ) ) || isset( $_POST[ 'icl_ajx_action' ] ) || isset( $_POST[ '_ajax_nonce' ] ) ) {
  8331. return;
  8332. }
  8333. $parts = parse_url( admin_url() );
  8334. $cookie_path = $parts[ 'path' ];
  8335. if ( $lang === false )
  8336. $lang = $this->get_current_language();
  8337. setcookie( '_icl_current_admin_language', $lang, time() + 7200, $cookie_path );
  8338. }
  8339. }
  8340. function get_admin_language_cookie()
  8341. {
  8342. static $active_languages = false;
  8343. if ( isset( $_COOKIE[ '_icl_current_admin_language' ] ) ) {
  8344. $lang = $_COOKIE[ '_icl_current_admin_language' ];
  8345. if(!$active_languages) {
  8346. $active_languages = $this->get_active_languages();
  8347. }
  8348. if ( !isset( $active_languages[ $lang ] ) && $lang != 'all' ) {
  8349. $lang = $this->get_default_language();
  8350. }
  8351. } else {
  8352. $lang = '';
  8353. }
  8354. return $lang;
  8355. }
  8356. function reset_admin_language_cookie()
  8357. {
  8358. $this->set_admin_language_cookie( $this->get_default_language() );
  8359. }
  8360. function rewrite_rules_filter( $value ) {
  8361. $current_language = $this->get_current_language();
  8362. $default_language = $this->get_default_language();
  8363. $directory_for_default_language = false;
  8364. $setting_url = $this->get_setting( 'urls' );
  8365. if ( $setting_url ) {
  8366. $directory_for_default_language = $setting_url[ 'directory_for_default_language' ];
  8367. }
  8368. if ( $this->get_setting( 'language_negotiation_type' ) == 1 && ( $current_language != $default_language || $directory_for_default_language ) ) {
  8369. foreach ( (array)$value as $k => $v ) {
  8370. $value[ $current_language . '/' . $k ] = $v;
  8371. unset( $value[ $k ] );
  8372. }
  8373. $value[ $current_language . '/?$' ] = 'index.php';
  8374. }
  8375. return $value;
  8376. }
  8377. function is_rtl( $lang = false )
  8378. {
  8379. if ( is_admin() ) {
  8380. if ( empty( $lang ) )
  8381. $lang = $this->get_admin_language();
  8382. } else {
  8383. if ( empty( $lang ) )
  8384. $lang = $this->get_current_language();
  8385. }
  8386. return in_array( $lang, array( 'ar', 'he', 'fa', 'ku' ) );
  8387. }
  8388. function get_translatable_documents( $include_not_synced = false )
  8389. {
  8390. global $wp_post_types;
  8391. $icl_post_types = array();
  8392. $attachment_is_translatable = $this->is_translated_post_type( 'attachment' );
  8393. $exceptions = array( 'revision', 'nav_menu_item' );
  8394. if(!$attachment_is_translatable) {
  8395. $exceptions[] = 'attachment';
  8396. }
  8397. foreach ( $wp_post_types as $k => $v ) {
  8398. if ( !in_array( $k, $exceptions ) ) {
  8399. if ( !$include_not_synced && ( empty( $this->settings[ 'custom_posts_sync_option' ][ $k ] ) || $this->settings[ 'custom_posts_sync_option' ][ $k ] != 1 ) && !in_array( $k, array( 'post', 'page' ) ) )
  8400. continue;
  8401. $icl_post_types[ $k ] = $v;
  8402. }
  8403. }
  8404. $icl_post_types = apply_filters( 'get_translatable_documents', $icl_post_types );
  8405. return $icl_post_types;
  8406. }
  8407. function get_translatable_taxonomies( $include_not_synced = false, $object_type = 'post' )
  8408. {
  8409. global $wp_taxonomies;
  8410. $t_taxonomies = array();
  8411. if ( $include_not_synced ) {
  8412. if ( in_array( $object_type, $wp_taxonomies[ 'post_tag' ]->object_type ) )
  8413. $t_taxonomies[ ] = 'post_tag';
  8414. if ( in_array( $object_type, $wp_taxonomies[ 'category' ]->object_type ) )
  8415. $t_taxonomies[ ] = 'category';
  8416. }
  8417. foreach ( $wp_taxonomies as $taxonomy_name => $taxonomy ) {
  8418. // exceptions
  8419. if ( 'post_format' == $taxonomy_name )
  8420. continue;
  8421. if ( in_array( $object_type, $taxonomy->object_type ) && !empty( $this->settings[ 'taxonomies_sync_option' ][ $taxonomy_name ] ) ) {
  8422. $t_taxonomies[ ] = $taxonomy_name;
  8423. }
  8424. }
  8425. if ( has_filter( 'get_translatable_taxonomies' ) ) {
  8426. $filtered = apply_filters( 'get_translatable_taxonomies', array( 'taxs' => $t_taxonomies, 'object_type' => $object_type ) );
  8427. $t_taxonomies = $filtered[ 'taxs' ];
  8428. if ( empty( $t_taxonomies ) )
  8429. $t_taxonomies = array();
  8430. }
  8431. return $t_taxonomies;
  8432. }
  8433. function is_translated_taxonomy( $tax )
  8434. {
  8435. global $sitepress_settings;
  8436. $settings = empty( $sitepress_settings ) ? $this->settings : $sitepress_settings;
  8437. $ret = false;
  8438. if ( is_scalar( $tax ) ) {
  8439. switch ( $tax ) {
  8440. case 'category':
  8441. case 'post_tag':
  8442. $ret = true;
  8443. break;
  8444. default:
  8445. if ( isset( $settings[ 'taxonomies_sync_option' ][ $tax ] ) ) {
  8446. $ret = $settings[ 'taxonomies_sync_option' ][ $tax ];
  8447. } elseif ( isset( $settings[ 'translation-management' ][ 'taxonomies_readonly_config' ][ $tax ] ) && $settings[ 'translation-management' ][ 'taxonomies_readonly_config' ][ $tax ] == 1 ) {
  8448. $ret = true;
  8449. } else {
  8450. $ret = false;
  8451. }
  8452. }
  8453. }
  8454. return $ret;
  8455. }
  8456. function is_translated_post_type( $type )
  8457. {
  8458. global $sitepress_settings;
  8459. $settings = empty( $sitepress_settings ) ? $this->settings : $sitepress_settings;
  8460. $ret = false;
  8461. if ( is_scalar( $type ) ) {
  8462. switch ( $type ) {
  8463. case 'post':
  8464. case 'page':
  8465. $ret = true;
  8466. break;
  8467. default:
  8468. if ( isset( $settings[ 'custom_posts_sync_option' ][ $type ] ) ) {
  8469. $ret = $settings[ 'custom_posts_sync_option' ][ $type ];
  8470. } elseif ( isset( $settings[ 'translation-management' ][ 'custom_types_readonly_config' ][ $type ] ) ) {
  8471. $ret = $settings[ 'translation-management' ][ 'custom_types_readonly_config' ][ $type ];
  8472. } else {
  8473. $ret = false;
  8474. }
  8475. }
  8476. }
  8477. return $ret;
  8478. }
  8479. function print_translatable_custom_content_status()
  8480. {
  8481. global $wp_taxonomies;
  8482. $icl_post_types = $this->get_translatable_documents( true );
  8483. $cposts = array();
  8484. $notice = '';
  8485. foreach ( $icl_post_types as $k => $v ) {
  8486. if ( !in_array( $k, array( 'post', 'page' ) ) ) {
  8487. $cposts[ $k ] = $v;
  8488. }
  8489. }
  8490. foreach ( $cposts as $k => $cpost ) {
  8491. if ( !isset( $this->settings[ 'custom_posts_sync_option' ][ $k ] ) ) {
  8492. $cposts_sync_not_set[ ] = $cpost->labels->name;
  8493. }
  8494. }
  8495. if ( defined( 'WPML_TM_VERSION' ) && !empty( $cposts_sync_not_set ) ) {
  8496. $notice = '<p class="updated fade">';
  8497. $notice .= sprintf( __( "You haven't set your <a %s>synchronization preferences</a> for these custom posts: %s. Default value was selected.", 'sitepress' ), 'href="admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup"', '<i>' . join( '</i>, <i>', $cposts_sync_not_set ) . '</i>' );
  8498. $notice .= '</p>';
  8499. }
  8500. $icl_post_types = $this->get_translatable_documents( true );
  8501. if ( defined( 'WPML_TM_VERSION' ) && $icl_post_types ) {
  8502. global $wpdb, $sitepress_settings;
  8503. $default_language = $this->get_default_language();
  8504. $custom_posts = array();
  8505. $icl_post_types = $this->get_translatable_documents( true );
  8506. foreach ( $icl_post_types as $k => $v ) {
  8507. if ( !in_array( $k, array( 'post', 'page' ) ) ) {
  8508. $custom_posts[ $k ] = $v;
  8509. }
  8510. }
  8511. foreach ( $custom_posts as $k => $custom_post ) {
  8512. $_has_slug = isset( $custom_post->rewrite[ 'slug' ] ) && $custom_post->rewrite[ 'slug' ];
  8513. $_translate = !empty($sitepress_settings['posts_slug_translation']['types'][$k]);
  8514. if ( $_has_slug ) {
  8515. if (isset($sitepress_settings[ 'st' ]) && $default_language != $sitepress_settings[ 'st' ][ 'strings_language' ] ) {
  8516. $string_id_prepared = $wpdb->prepare( "
  8517. SELECT s.id FROM {$wpdb->prefix}icl_strings s
  8518. JOIN {$wpdb->prefix}icl_string_translations st
  8519. ON st.string_id = s.id
  8520. WHERE st.language=%s AND s.value=%s AND s.name LIKE %s
  8521. ", array( $default_language, $custom_post->rewrite[ 'slug' ], 'URL slug: %' ) );
  8522. } else {
  8523. $string_id_prepared = $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}icl_strings WHERE name = %s AND value = %s ", array(
  8524. 'Url slug: ' . $custom_post->rewrite[ 'slug' ],
  8525. $custom_post->rewrite[ 'slug' ]
  8526. ) );
  8527. }
  8528. $string_id = $wpdb->get_var( $string_id_prepared );
  8529. if ( $_translate && !$string_id ) {
  8530. $message = sprintf( __( "%s slugs are set to be translated, but they are missing their translation", 'sitepress'), $custom_post->labels->name);
  8531. $notice .= ICL_AdminNotifier::displayInstantMessage( $message, 'error', 'below-h2', true );
  8532. }
  8533. }
  8534. }
  8535. }
  8536. $ctaxonomies = array_diff( array_keys( (array)$wp_taxonomies ), array( 'post_tag', 'category', 'nav_menu', 'link_category', 'post_format' ) );
  8537. foreach ( $ctaxonomies as $ctax ) {
  8538. if ( !isset( $this->settings[ 'taxonomies_sync_option' ][ $ctax ] ) ) {
  8539. $tax_sync_not_set[ ] = $wp_taxonomies[ $ctax ]->label;
  8540. }
  8541. }
  8542. if ( defined( 'WPML_TM_VERSION' ) && !empty( $tax_sync_not_set ) ) {
  8543. $notice .= '<p class="updated">';
  8544. $notice .= sprintf( __( "You haven't set your <a %s>synchronization preferences</a> for these taxonomies: %s. Default value was selected.", 'sitepress' ), 'href="admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup"', '<i>' . join( '</i>, <i>', $tax_sync_not_set ) . '</i>' );
  8545. $notice .= '</p>';
  8546. }
  8547. echo $notice;
  8548. }
  8549. function dashboard_widget_setup()
  8550. {
  8551. if ( current_user_can( 'manage_options' ) ) {
  8552. $dashboard_widgets_order = (array)get_user_option( "meta-box-order_dashboard" );
  8553. $icl_dashboard_widget_id = 'icl_dashboard_widget';
  8554. $all_widgets = array();
  8555. foreach ( $dashboard_widgets_order as $v ) {
  8556. $all_widgets = array_merge( $all_widgets, explode( ',', $v ) );
  8557. }
  8558. if ( !in_array( $icl_dashboard_widget_id, $all_widgets ) ) {
  8559. $install = true;
  8560. } else {
  8561. $install = false;
  8562. }
  8563. wp_add_dashboard_widget( $icl_dashboard_widget_id, sprintf( __( 'Multi-language | WPML %s', 'sitepress' ), ICL_SITEPRESS_VERSION ), array( $this, 'dashboard_widget' ), null );
  8564. if ( $install ) {
  8565. //FIXME: reported one case of NOTICE: wp-content/plugins/sitepress-multilingual-cms/sitepress.class.php:7815 - Undefined index: side
  8566. $dashboard_widgets_order[ 'side' ] = $icl_dashboard_widget_id . ',' . @strval( $dashboard_widgets_order[ 'side' ] );
  8567. $user = wp_get_current_user();
  8568. update_user_option( $user->ID, 'meta-box-order_dashboard', $dashboard_widgets_order, true );
  8569. }
  8570. }
  8571. }
  8572. function dashboard_widget()
  8573. {
  8574. do_action( 'icl_dashboard_widget_notices' );
  8575. include_once ICL_PLUGIN_PATH . '/menu/dashboard-widget.php';
  8576. }
  8577. function verify_post_translations( $post_type ) {
  8578. global $wpdb;
  8579. $active_languages = count( $this->get_active_languages() );
  8580. $sql = "
  8581. SELECT p1.ID, t.translation_id
  8582. FROM {$wpdb->prefix}icl_translations t
  8583. INNER JOIN {$wpdb->posts} p1
  8584. ON t.element_id = p1.ID
  8585. LEFT JOIN {$wpdb->prefix}icl_translations tt
  8586. ON t.trid = tt.trid
  8587. WHERE t.element_type = %s
  8588. AND t.source_language_code IS null
  8589. GROUP BY p1.ID, p1.post_parent
  8590. HAVING count(tt.language_code) < %d
  8591. ";
  8592. $sql_prepared = $wpdb->prepare( $sql, array( 'post_' . $post_type, $active_languages ) );
  8593. $results = $wpdb->get_results( $sql_prepared );
  8594. if ( $results ) {
  8595. foreach ( $results as $result ) {
  8596. $id = $result->ID;
  8597. $translation_id = $result->translation_id;
  8598. if ( !$translation_id ) {
  8599. $this->set_element_language_details( $id, 'post_' . $post_type, false, $this->get_default_language() );
  8600. }
  8601. }
  8602. } else {
  8603. $post_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->posts} WHERE post_type='{$post_type}' AND post_status <> 'auto-draft'" );
  8604. if ( !empty( $post_ids ) ) {
  8605. foreach ( $post_ids as $id ) {
  8606. $translation_id_prepared = $wpdb->prepare( "SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", array( $id, 'post_' . $post_type ) );
  8607. $translation_id = $wpdb->get_var( $translation_id_prepared );
  8608. if ( !$translation_id ) {
  8609. $this->set_element_language_details( $id, 'post_' . $post_type, false, $this->get_default_language() );
  8610. }
  8611. }
  8612. }
  8613. }
  8614. }
  8615. function verify_taxonomy_translations( $taxonomy )
  8616. {
  8617. global $wpdb;
  8618. $element_ids_prepared = $wpdb->prepare( "SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE taxonomy=%s", $taxonomy);
  8619. $element_ids = $wpdb->get_col( $element_ids_prepared );
  8620. if ( !empty( $element_ids ) ) {
  8621. foreach ( $element_ids as $id ) {
  8622. $translation_id_prepared = $wpdb->prepare( "SELECT translation_id FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", $id, 'tax_' . $taxonomy);
  8623. $translation_id = $wpdb->get_var( $translation_id_prepared );
  8624. if ( !$translation_id ) {
  8625. $this->set_element_language_details( $id, 'tax_' . $taxonomy, false, $this->get_default_language() );
  8626. }
  8627. }
  8628. }
  8629. }
  8630. function copy_from_original()
  8631. {
  8632. global $wpdb;
  8633. $show = false;
  8634. $trid = false;
  8635. $source_lang = false;
  8636. $source_lang_name = false;
  8637. $disabled = '';
  8638. if ( isset( $_GET[ 'source_lang' ] ) && isset( $_GET[ 'trid' ] ) ) {
  8639. $source_lang = $_GET[ 'source_lang' ];
  8640. $trid = intval( $_GET[ 'trid' ] );
  8641. $_lang_details = $this->get_language_details( $source_lang );
  8642. $source_lang_name = $_lang_details[ 'display_name' ];
  8643. $show = true;
  8644. } elseif ( isset( $_GET[ 'post' ] ) && isset( $_GET[ 'lang' ] ) && $_GET[ 'lang' ] != $this->get_default_language() ) {
  8645. global $post;
  8646. if ( trim( $post->post_content ) ) {
  8647. $disabled = ' disabled="disabled"';
  8648. }
  8649. $trid = $this->get_element_trid( $post->ID, 'post_' . $post->post_type );
  8650. $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 ) );
  8651. $_lang_details = $this->get_language_details( $source_lang );
  8652. $source_lang_name = $_lang_details[ 'display_name' ];
  8653. $show = true && $source_lang;
  8654. }
  8655. if ( $show ) {
  8656. wp_nonce_field( 'copy_from_original_nonce', '_icl_nonce_cfo_' . $trid );
  8657. echo '<input id="icl_cfo" class="button-secondary" type="button" value="' . sprintf( __( 'Copy content from %s', 'sitepress' ), $source_lang_name ) . '"
  8658. onclick="icl_copy_from_original(\'' . esc_js( $source_lang ) . '\', \'' . esc_js( $trid ) . '\')"' . $disabled . '/>';
  8659. 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' );
  8660. echo '<br clear="all" />';
  8661. }
  8662. }
  8663. function wp_upgrade_locale( $locale )
  8664. {
  8665. if ( defined( 'WPLANG' ) && WPLANG ) {
  8666. $locale = WPLANG;
  8667. } else {
  8668. $locale = ICL_WP_UPDATE_LOCALE;
  8669. }
  8670. return $locale;
  8671. }
  8672. function admin_language_switcher_legacy()
  8673. {
  8674. global $pagenow, $wpdb;
  8675. $all_languages_enabled = true;
  8676. $current_page = basename( $_SERVER[ 'SCRIPT_NAME' ] );
  8677. $current_language = $this->get_current_language();
  8678. // individual translations
  8679. $is_post = false;
  8680. $is_tax = false;
  8681. $is_menu = false;
  8682. $post_type = false;
  8683. $trid = false;
  8684. $translations = false;
  8685. switch ( $pagenow ) {
  8686. case 'post.php':
  8687. $is_post = true;
  8688. $all_languages_enabled = false;
  8689. $post_id = @intval( $_GET[ 'post' ] );
  8690. $post = get_post( $post_id );
  8691. $trid = $this->get_element_trid( $post_id, 'post_' . $post->post_type );
  8692. $translations = $this->get_element_translations( $trid, 'post_' . $post->post_type, true );
  8693. break;
  8694. case 'post-new.php':
  8695. $all_languages_enabled = false;
  8696. if ( isset( $_GET[ 'trid' ] ) ) {
  8697. $trid = intval( $_GET[ 'trid' ] );
  8698. $post_type = isset( $_GET[ 'post_type' ] ) ? $_GET[ 'post_type' ] : 'post';
  8699. $translations = $this->get_element_translations( $trid, 'post_' . $post_type, true );
  8700. $is_post = true;
  8701. }
  8702. break;
  8703. case 'edit-tags.php':
  8704. $is_tax = true;
  8705. if ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'edit' ) {
  8706. $all_languages_enabled = false;
  8707. }
  8708. $term_id = @intval( $_GET[ 'tag_ID' ] );
  8709. $taxonomy = $_GET[ 'taxonomy' ];
  8710. $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 ) );
  8711. $trid = $this->get_element_trid( $term_tax_id, 'tax_' . $taxonomy );
  8712. $translations = $this->get_element_translations( $trid, 'tax_' . $taxonomy, true );
  8713. break;
  8714. case 'nav-menus.php':
  8715. $is_menu = true;
  8716. if ( isset( $_GET[ 'menu' ] ) && $_GET[ 'menu' ] ) {
  8717. $menu_id = $_GET[ 'menu' ];
  8718. $trid = $trid = $this->get_element_trid( $menu_id, 'tax_nav_menu' );
  8719. $translations = $this->get_element_translations( $trid, 'tax_nav_menu', true );
  8720. }
  8721. $all_languages_enabled = false;
  8722. break;
  8723. }
  8724. foreach ( $this->get_active_languages() as $lang ) {
  8725. $current_page_lang = $current_page;
  8726. parse_str( $_SERVER[ 'QUERY_STRING' ], $query_vars );
  8727. unset( $query_vars[ 'lang' ], $query_vars[ 'admin_bar' ] );
  8728. // individual translations
  8729. if ( $is_post ) {
  8730. if ( isset( $translations[ $lang[ 'code' ] ] ) && isset( $translations[ $lang[ 'code' ] ]->element_id ) ) {
  8731. $query_vars[ 'post' ] = $translations[ $lang[ 'code' ] ]->element_id;
  8732. unset( $query_vars[ 'source_lang' ] );
  8733. $current_page_lang = 'post.php';
  8734. $query_vars[ 'action' ] = 'edit';
  8735. } else {
  8736. $current_page_lang = 'post-new.php';
  8737. if ( isset( $post ) ) {
  8738. $query_vars[ 'post_type' ] = $post->post_type;
  8739. $query_vars[ 'source_lang' ] = $current_language;
  8740. } else {
  8741. $query_vars[ 'post_type' ] = $post_type;
  8742. }
  8743. $query_vars[ 'trid' ] = $trid;
  8744. unset( $query_vars[ 'post' ], $query_vars[ 'action' ] );
  8745. }
  8746. } elseif ( $is_tax ) {
  8747. if ( isset( $translations[ $lang[ 'code' ] ] ) && isset( $translations[ $lang[ 'code' ] ]->element_id ) ) {
  8748. $query_vars[ 'tag_ID' ] = $translations[ $lang[ 'code' ] ]->element_id;
  8749. } else {
  8750. $query_vars[ 'trid' ] = $trid;
  8751. $query_vars[ 'source_lang' ] = $current_language;
  8752. unset( $query_vars[ 'tag_ID' ], $query_vars[ 'action' ] );
  8753. }
  8754. } elseif ( $is_menu ) {
  8755. if ( !empty( $menu_id ) ) {
  8756. if ( isset( $translations[ $lang[ 'code' ] ]->element_id ) ) {
  8757. $query_vars[ 'menu' ] = $translations[ $lang[ 'code' ] ]->element_id;
  8758. } else {
  8759. $query_vars[ 'menu' ] = 0;
  8760. $query_vars[ 'trid' ] = $trid;
  8761. $query_vars[ 'action' ] = 'edit';
  8762. }
  8763. }
  8764. }
  8765. $query_string = http_build_query( $query_vars );
  8766. $query = '?';
  8767. if ( !empty( $query_string ) ) {
  8768. $query .= $query_string . '&';
  8769. }
  8770. $query .= 'lang=' . $lang[ 'code' ]; // the default language need to specified explictly yoo in order to set the lang cookie
  8771. $link_url = admin_url( $current_page_lang . $query );
  8772. $flag = $this->get_flag( $lang[ 'code' ] );
  8773. if ( $flag->from_template ) {
  8774. $wp_upload_dir = wp_upload_dir();
  8775. $flag_url = $wp_upload_dir[ 'baseurl' ] . '/flags/' . $flag->flag;
  8776. } else {
  8777. $flag_url = ICL_PLUGIN_URL . '/res/flags/' . $flag->flag;
  8778. }
  8779. $languages_links[ $lang[ 'code' ] ] = array(
  8780. 'url' => $link_url . '&admin_bar=1', 'current' => $lang[ 'code' ] == $current_language, 'anchor' => $lang[ 'display_name' ],
  8781. 'flag' => '<img class="admin_iclflag" src="' . $flag_url . '" alt="' . $lang[ 'code' ] . '" width="18" height="12" />'
  8782. );
  8783. }
  8784. if ( $all_languages_enabled ) {
  8785. $query = '?';
  8786. if ( !empty( $query_string ) ) {
  8787. $query .= $query_string . '&';
  8788. }
  8789. $query .= 'lang=all';
  8790. $link_url = admin_url( basename( $_SERVER[ 'SCRIPT_NAME' ] ) . $query );
  8791. $languages_links[ 'all' ] = array(
  8792. 'url' => $link_url, 'current' => 'all' == $current_language, 'anchor' => __( 'All languages', 'sitepress' ),
  8793. 'flag' => '<img class="admin_iclflag" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" alt="all" width="16" height="16" />'
  8794. );
  8795. } else {
  8796. // set the default language as current
  8797. if ( 'all' == $current_language ) {
  8798. $languages_links[ $this->get_default_language() ][ 'current' ] = true;
  8799. }
  8800. }
  8801. include ICL_PLUGIN_PATH . '/menu/admin-language-switcher.php';
  8802. }
  8803. function admin_language_switcher()
  8804. {
  8805. if(!SitePress::check_settings_integrity()) return;
  8806. /** @var $wp_admin_bar WP_Admin_Bar */
  8807. global $wpdb, $wp_admin_bar, $pagenow, $mode;
  8808. $all_languages_enabled = true;
  8809. $current_page = basename( $_SERVER[ 'SCRIPT_NAME' ] );
  8810. $post_type = false;
  8811. $trid = false;
  8812. $translations = false;
  8813. $languages_links = array();
  8814. // individual translations
  8815. $is_post = false;
  8816. $is_tax = false;
  8817. $is_menu = false;
  8818. $current_language = $this->get_current_language();
  8819. switch ( $pagenow ) {
  8820. case 'post.php':
  8821. $is_post = true;
  8822. $post_id = @intval( $_GET[ 'post' ] );
  8823. $post = get_post( $post_id );
  8824. $post_language = $this->get_language_for_element( $post_id, 'post_' . get_post_type( $post_id ) );
  8825. if ( $post_language && $post_language != $current_language ) {
  8826. $this->switch_lang( $post_language );
  8827. $current_language = $this->get_current_language();
  8828. }
  8829. $trid = $this->get_element_trid( $post_id, 'post_' . $post->post_type );
  8830. $translations = $this->get_element_translations( $trid, 'post_' . $post->post_type, true );
  8831. break;
  8832. case 'post-new.php':
  8833. $all_languages_enabled = false;
  8834. if ( isset( $_GET[ 'trid' ] ) ) {
  8835. $trid = intval( $_GET[ 'trid' ] );
  8836. $post_type = isset( $_GET[ 'post_type' ] ) ? $_GET[ 'post_type' ] : 'post';
  8837. $translations = $this->get_element_translations( $trid, 'post_' . $post_type, true );
  8838. $is_post = true;
  8839. }
  8840. break;
  8841. case 'edit-tags.php':
  8842. $is_tax = true;
  8843. if ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'edit' ) {
  8844. $all_languages_enabled = false;
  8845. }
  8846. $taxonomy = $_GET['taxonomy'];
  8847. $term_tax_id = 0;
  8848. if ( isset( $_GET[ 'tag_ID' ] ) ) {
  8849. $term_id = @intval( $_GET[ 'tag_ID' ] );
  8850. $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 ) );
  8851. }
  8852. if ( $term_tax_id ) {
  8853. $trid = $this->get_element_trid( $term_tax_id, 'tax_' . $taxonomy );
  8854. }
  8855. if ( $trid ) {
  8856. $translations = $this->get_element_translations( $trid, 'tax_' . $taxonomy, true );
  8857. }
  8858. break;
  8859. case 'nav-menus.php':
  8860. $is_menu = true;
  8861. if ( isset( $_GET[ 'menu' ] ) && $_GET[ 'menu' ] ) {
  8862. $menu_id = $_GET[ 'menu' ];
  8863. $trid = $trid = $this->get_element_trid( $menu_id, 'tax_nav_menu' );
  8864. $translations = $this->get_element_translations( $trid, 'tax_nav_menu', true );
  8865. }
  8866. $all_languages_enabled = false;
  8867. break;
  8868. case 'upload.php':
  8869. if ( $mode == 'grid' ) {
  8870. $all_languages_enabled = false;
  8871. }
  8872. break;
  8873. }
  8874. foreach ( $this->get_active_languages() as $lang ) {
  8875. $current_page_lang = $current_page;
  8876. if ( isset( $_SERVER[ 'QUERY_STRING' ] ) ) {
  8877. parse_str( $_SERVER[ 'QUERY_STRING' ], $query_vars );
  8878. unset( $query_vars[ 'lang' ], $query_vars[ 'admin_bar' ] );
  8879. } else {
  8880. $query_vars = array();
  8881. }
  8882. // individual translations
  8883. if ( $is_post ) {
  8884. if ( isset( $translations[ $lang[ 'code' ] ] ) && isset( $translations[ $lang[ 'code' ] ]->element_id ) ) {
  8885. $query_vars[ 'post' ] = $translations[ $lang[ 'code' ] ]->element_id;
  8886. unset( $query_vars[ 'source_lang' ] );
  8887. $current_page_lang = 'post.php';
  8888. $query_vars[ 'action' ] = 'edit';
  8889. } else {
  8890. $current_page_lang = 'post-new.php';
  8891. if ( isset( $post ) ) {
  8892. $query_vars[ 'post_type' ] = $post->post_type;
  8893. $query_vars[ 'source_lang' ] = $current_language;
  8894. } else {
  8895. $query_vars[ 'post_type' ] = $post_type;
  8896. }
  8897. $query_vars[ 'trid' ] = $trid;
  8898. unset( $query_vars[ 'post' ], $query_vars[ 'action' ] );
  8899. }
  8900. } elseif ( $is_tax ) {
  8901. if ( isset( $translations[ $lang[ 'code' ] ] ) && isset( $translations[ $lang[ 'code' ] ]->element_id ) ) {
  8902. $query_vars[ 'tag_ID' ] = $translations[ $lang[ 'code' ] ]->element_id;
  8903. } else {
  8904. $query_vars[ 'trid' ] = $trid;
  8905. $query_vars[ 'source_lang' ] = $current_language;
  8906. unset( $query_vars[ 'tag_ID' ], $query_vars[ 'action' ] );
  8907. }
  8908. } elseif ( $is_menu ) {
  8909. if ( !empty( $menu_id ) ) {
  8910. if ( isset( $translations[ $lang[ 'code' ] ]->element_id ) ) {
  8911. $query_vars[ 'menu' ] = $translations[ $lang[ 'code' ] ]->element_id;
  8912. } else {
  8913. $query_vars[ 'menu' ] = 0;
  8914. $query_vars[ 'trid' ] = $trid;
  8915. $query_vars[ 'action' ] = 'edit';
  8916. }
  8917. }
  8918. }
  8919. $query_string = http_build_query( $query_vars );
  8920. $query = '?';
  8921. if ( !empty( $query_string ) ) {
  8922. $query .= $query_string . '&';
  8923. }
  8924. $query .= 'lang=' . $lang[ 'code' ]; // the default language need to specified explicitly yoo in order to set the lang cookie
  8925. $link_url = admin_url( $current_page_lang . $query );
  8926. $flag = $this->get_flag( $lang[ 'code' ] );
  8927. if ( $flag->from_template ) {
  8928. $wp_upload_dir = wp_upload_dir();
  8929. $flag_url = $wp_upload_dir[ 'baseurl' ] . '/flags/' . $flag->flag;
  8930. } else {
  8931. $flag_url = ICL_PLUGIN_URL . '/res/flags/' . $flag->flag;
  8932. }
  8933. $languages_links[ $lang[ 'code' ] ] = array(
  8934. 'url' => $link_url . '&admin_bar=1',
  8935. 'current' => $lang[ 'code' ] == $current_language,
  8936. 'anchor' => $lang[ 'display_name' ],
  8937. 'flag' => '<img class="icl_als_iclflag" src="' . $flag_url . '" alt="' . $lang[ 'code' ] . '" width="18" height="12" />'
  8938. );
  8939. }
  8940. if ( $all_languages_enabled ) {
  8941. $query = '?';
  8942. if ( !empty( $query_string ) ) {
  8943. $query .= $query_string . '&';
  8944. }
  8945. $query .= 'lang=all';
  8946. $link_url = admin_url( basename( $_SERVER[ 'SCRIPT_NAME' ] ) . $query );
  8947. $languages_links[ 'all' ] = array(
  8948. 'url' => $link_url, 'current' => 'all' == $current_language, 'anchor' => __( 'All languages', 'sitepress' ),
  8949. 'flag' => '<img class="icl_als_iclflag" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" alt="all" width="16" height="16" />'
  8950. );
  8951. } else {
  8952. // set the default language as current
  8953. if ( 'all' == $current_language ) {
  8954. $current_language = $this->get_default_language();
  8955. $languages_links[ $current_language ][ 'current' ] = true;
  8956. }
  8957. }
  8958. $parent = 'WPML_ALS';
  8959. $lang = $languages_links[ $current_language ];
  8960. // Current language
  8961. $wp_admin_bar->add_menu( array(
  8962. 'parent' => false, 'id' => $parent,
  8963. 'title' => $lang[ 'flag' ] . '&nbsp;' . $lang[ 'anchor' ] . '&nbsp;&nbsp;<img title="' . __( 'help', 'sitepress' ) . '" id="wpml_als_help_link" src="' . ICL_PLUGIN_URL . '/res/img/question1.png" alt="' . __( 'help', 'sitepress' ) . '" width="16" height="16"/>',
  8964. 'href' => false, 'meta' => array(
  8965. 'title' => __( 'Showing content in:', 'sitepress' ) . ' ' . $lang[ 'anchor' ],
  8966. )
  8967. ) );
  8968. if ( $languages_links ) {
  8969. foreach ( $languages_links as $code => $lang ) {
  8970. if ( $code == $current_language )
  8971. continue;
  8972. $wp_admin_bar->add_menu( array(
  8973. 'parent' => $parent, 'id' => $parent . '_' . $code, 'title' => $lang[ 'flag' ] . '&nbsp;' . $lang[ 'anchor' ], 'href' => $lang[ 'url' ], 'meta' => array(
  8974. 'title' => __( 'Show content in:', 'sitepress' ) . ' ' . $lang[ 'anchor' ],
  8975. )
  8976. ) );
  8977. }
  8978. }
  8979. add_action( 'all_admin_notices', array( $this, '_admin_language_switcher_help_popup' ) );
  8980. }
  8981. function _admin_language_switcher_help_popup()
  8982. {
  8983. echo '<div id="icl_als_help_popup" class="icl_cyan_box icl_pop_info">';
  8984. echo '<img class="icl_pop_info_but_close" align="right" src="' . ICL_PLUGIN_URL . '/res/img/ico-close.png" width="12" height="12" alt="x" />';
  8985. printf( __( 'This language selector determines which content to display. You can choose items in a specific language or in all languages. To change the language of the WordPress Admin interface, go to <a%s>your profile</a>.', 'sitepress' ), ' href="' . admin_url( 'profile.php' ) . '"' );
  8986. echo '</div>';
  8987. }
  8988. function admin_notices( $message, $class = "updated" )
  8989. {
  8990. static $hook_added = 0;
  8991. $this->_admin_notices[ ] = array( 'class' => $class, 'message' => $message );
  8992. if ( !$hook_added )
  8993. add_action( 'admin_notices', array( $this, '_admin_notices_hook' ) );
  8994. $hook_added = 1;
  8995. }
  8996. function _admin_notices_hook()
  8997. {
  8998. if ( !empty( $this->_admin_notices ) )
  8999. foreach ( $this->_admin_notices as $n ) {
  9000. echo '<div class="' . $n[ 'class' ] . '">';
  9001. echo '<p>' . $n[ 'message' ] . '</p>';
  9002. echo '</div>';
  9003. }
  9004. }
  9005. /**
  9006. * Adjust template (taxonomy-)$taxonomy-$term.php for translated term slugs and IDs
  9007. *
  9008. * @since 3.1
  9009. *
  9010. * @param string $template
  9011. *
  9012. * @return string The template filename if found.
  9013. */
  9014. function slug_template($template){
  9015. global $wp_query;
  9016. $term = $wp_query->get_queried_object();
  9017. //Taxonomies
  9018. if(!isset($term) || !$term) return $template;
  9019. $taxonomy = $term->taxonomy;
  9020. if(!isset($taxonomy) || !$taxonomy) return $template;
  9021. $templates = array();
  9022. $template_prefix = 'taxonomy-';
  9023. $is_taxonomy = true;
  9024. if(in_array($taxonomy, array('category','tag'))) {
  9025. $template_prefix = '';
  9026. $is_taxonomy = false;
  9027. }
  9028. remove_filter( 'get_term', array( $this, 'get_term_adjust_id' ), 1 );
  9029. $current_language = $this->get_current_language();
  9030. $default_language = $this->get_default_language();
  9031. if (!$is_taxonomy || $this->is_translated_taxonomy( $taxonomy ) && $current_language != $default_language ) {
  9032. $current_term = get_term_by( "id", $term->term_id, $taxonomy );
  9033. if ( $current_term ) {
  9034. $templates[ ] = "$template_prefix$taxonomy-{$current_language}-{$current_term->slug}.php";
  9035. $templates[ ] = "$template_prefix$taxonomy-{$current_language}-{$term->term_id}.php";
  9036. $templates[ ] = "$template_prefix$taxonomy-{$current_language}.php";
  9037. $templates[ ] = "$template_prefix$taxonomy-{$current_term->slug}.php";
  9038. $templates[ ] = "$template_prefix$taxonomy-{$term->term_id}.php";
  9039. }
  9040. }
  9041. $original_term_id = icl_object_id( $term->term_id, $taxonomy, true, $default_language );
  9042. $original_term = get_term_by( "id", $original_term_id, $taxonomy );
  9043. if ( $original_term ) {
  9044. $templates[ ] = "$template_prefix$taxonomy-{$current_language}-{$original_term->slug}.php";
  9045. $templates[ ] = "$template_prefix$taxonomy-{$current_language}-{$original_term_id}.php";
  9046. $templates[ ] = "$template_prefix$taxonomy-{$original_term->slug}.php";
  9047. $templates[ ] = "$template_prefix$taxonomy-{$original_term_id}.php";
  9048. $templates[ ] = "$template_prefix$taxonomy-{$current_language}.php";
  9049. $templates[ ] = "$template_prefix$taxonomy.php";
  9050. }
  9051. if ( $is_taxonomy ) {
  9052. $templates[ ] = 'taxonomy-{$current_language}.php';
  9053. $templates[ ] = 'taxonomy.php';
  9054. }
  9055. $templates = array_unique($templates);
  9056. add_filter( 'get_term', array( $this, 'get_term_adjust_id' ), 1, 1 );
  9057. $new_template = locate_template( $templates );
  9058. if($new_template) {
  9059. $template = $new_template;
  9060. }
  9061. return $template;
  9062. }
  9063. function setup_canonical_urls()
  9064. {
  9065. global $wp_the_query;
  9066. // Yoast Exception
  9067. global $wpseo_front;
  9068. if ( isset( $wpseo_front ) && has_filter( 'wp_head', array( $wpseo_front, 'head' ) ) )
  9069. return;
  9070. if ( is_singular() ) {
  9071. $id = $wp_the_query->get_queried_object_id();
  9072. $master_post_id = get_post_meta( $id, '_icl_lang_duplicate_of', true );
  9073. if ( $id && $master_post_id != $id ) {
  9074. remove_action( 'wp_head', 'rel_canonical' );
  9075. add_action( 'wp_head', array( $this, 'rel_canonical' ) );
  9076. }
  9077. }
  9078. }
  9079. function rel_canonical()
  9080. {
  9081. global $wp_the_query;
  9082. $id = $wp_the_query->get_queried_object_id();
  9083. if ( $master_post_id = get_post_meta( $id, '_icl_lang_duplicate_of', true ) ) {
  9084. $link = get_permalink( $master_post_id );
  9085. echo "<link rel='canonical' href='$link' />\n";
  9086. }
  9087. }
  9088. function head_langs()
  9089. {
  9090. $languages = $this->get_ls_languages( array( 'skip_missing' => true ) );
  9091. // If there are translations and is not paged content...
  9092. //Renders head alternate links only on certain conditions
  9093. $the_post = get_post();
  9094. $the_id = $the_post ? $the_post->ID : false;
  9095. $is_valid = count( $languages ) > 1 && !is_paged() && ( ( ( is_single() || is_page() ) && $the_id && get_post_status( $the_id ) == 'publish' ) || ( is_home() || is_front_page() || is_archive() ) );
  9096. if ( $is_valid ) {
  9097. foreach ( $languages as $code => $lang ) {
  9098. printf( '<link rel="alternate" hreflang="%s" href="%s" />' . PHP_EOL, $this->get_language_tag( $code ), str_replace( '&amp;', '&', $lang[ 'url' ] ) );
  9099. }
  9100. }
  9101. }
  9102. function allowed_redirect_hosts( $hosts )
  9103. {
  9104. if ( $this->settings[ 'language_negotiation_type' ] == 2 ) {
  9105. foreach ( $this->settings[ 'language_domains' ] as $code => $url ) {
  9106. if ( !empty( $this->active_languages[ $code ] ) ) {
  9107. $parts = parse_url( $url );
  9108. if ( !in_array( $parts[ 'host' ], $hosts ) ) {
  9109. $hosts[ ] = $parts[ 'host' ];
  9110. }
  9111. }
  9112. }
  9113. }
  9114. return $hosts;
  9115. }
  9116. function icl_nonces()
  9117. {
  9118. //@since 3.1 Calls made only when in Translation Management pages
  9119. $allowed_pages = array();
  9120. if(defined('WPML_TM_FOLDER')) {
  9121. $allowed_pages[] = WPML_TM_FOLDER . '/menu/main.php';
  9122. }
  9123. if(!isset($_REQUEST['page']) || !in_array($_REQUEST['page'], $allowed_pages)) {
  9124. return;
  9125. }
  9126. //messages
  9127. wp_nonce_field( 'icl_messages_nonce', '_icl_nonce_m' );
  9128. wp_nonce_field( 'icl_show_reminders_nonce', '_icl_nonce_sr' );
  9129. }
  9130. //For when it will be possible to add custom bulk actions
  9131. function bulk_actions($actions) {
  9132. $active_languages = $this->get_active_languages();
  9133. $actions['duplicate_all'] = 'duplicate_all';
  9134. foreach($active_languages as $language_code => $language_name) {
  9135. $actions['duplicate_' . $language_code] = 'duplicate_' . $language_code;
  9136. }
  9137. return $actions;
  9138. }
  9139. /**
  9140. * Returns SERVER_NAME, or HTTP_HOST if the first is not available
  9141. * @return mixed
  9142. */
  9143. private function get_server_host_name() {
  9144. if(!isset($_SERVER[ 'HTTP_HOST' ])) {
  9145. $host = $_SERVER[ 'SERVER_NAME' ];
  9146. if(isset( $_SERVER[ 'SERVER_PORT' ] ) && $_SERVER[ 'SERVER_PORT' ]!=80) {
  9147. $host .= ':' . $_SERVER[ 'SERVER_PORT' ];
  9148. }
  9149. } else {
  9150. $host = $_SERVER[ 'HTTP_HOST' ];
  9151. }
  9152. //Removes standard ports 443 (80 should be already omitted in all cases)
  9153. $result = preg_replace( "@:[443]+([/]?)@", '$1', $host );
  9154. return $result;
  9155. }
  9156. public static function get_installed_plugins() {
  9157. if(!function_exists('get_plugins')) {
  9158. require_once(ABSPATH . 'wp-admin/includes/plugin.php');
  9159. }
  9160. $wp_plugins = get_plugins();
  9161. $wpml_plugins_list = array(
  9162. 'WPML Multilingual CMS' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'sitepress-multilingual-cms' ),
  9163. 'WPML CMS Nav' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-cms-nav' ),
  9164. 'WPML String Translation' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-string-translation' ),
  9165. 'WPML Sticky Links' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-sticky-links' ),
  9166. 'WPML Translation Management' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-translation-management' ),
  9167. 'WPML Translation Analytics' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-translation-analytics' ),
  9168. 'WPML XLIFF' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-xliff' ),
  9169. 'WPML Media' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'wpml-media' ),
  9170. 'WooCommerce Multilingual' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'woocommerce-multilingual' ),
  9171. 'JigoShop Multilingual' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'jigoshop-multilingual' ),
  9172. 'Gravity Forms Multilingual' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'gravityforms-multilingual' ),
  9173. 'CRED Frontend Translation' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'cred-frontend-translation' ),
  9174. 'Installer' => array( 'installed' => false, 'active' => false, 'file' => false, 'plugin' => false, 'slug' => 'installer' ),
  9175. );
  9176. foreach ( $wpml_plugins_list as $wpml_plugin_name => $v ) {
  9177. foreach ( $wp_plugins as $file => $plugin ) {
  9178. $plugin_name = $plugin[ 'Name' ];
  9179. if ( $plugin_name == $wpml_plugin_name ) {
  9180. $wpml_plugins_list[ $plugin_name ][ 'installed' ] = true;
  9181. $wpml_plugins_list[ $plugin_name ][ 'plugin' ] = $plugin;
  9182. $wpml_plugins_list[ $plugin_name ][ 'file' ] = $file;
  9183. }
  9184. }
  9185. }
  9186. return $wpml_plugins_list;
  9187. }
  9188. public static function check_settings_integrity() {
  9189. if(wpml_is_ajax()) return true;
  9190. if ( isset( $_GET[ 'debug_action' ]) && $_GET[ 'nonce' ] == wp_create_nonce( $_GET[ 'debug_action' ] ) ) {
  9191. if($_GET[ 'debug_action' ] == 'reset_wpml_settings') {
  9192. $referrer = isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] ? $_SERVER['HTTP_REFERER'] : get_admin_url();
  9193. $current_settings = get_option( 'icl_sitepress_settings' );
  9194. unset($current_settings['setup_complete']);
  9195. unset($current_settings['setup_wizard_step']);
  9196. unset($current_settings['existing_content_language_verified']);
  9197. unset($current_settings['dont_show_help_admin_notice']);
  9198. global $wpdb;
  9199. $wpdb->query('TRUNCATE TABLE ' . $wpdb->prefix . 'icl_translations');
  9200. update_option('icl_sitepress_settings', $current_settings);
  9201. wp_redirect($referrer);
  9202. exit();
  9203. }
  9204. }
  9205. global $wpdb;
  9206. static $result;
  9207. if(isset($result)) {
  9208. return $result;
  9209. }
  9210. $current_settings = get_option( 'icl_sitepress_settings' );
  9211. if(!$current_settings) return true;
  9212. $setup_wizard_step = false;
  9213. if ( isset( $current_settings[ 'setup_wizard_step' ] ) ) {
  9214. $setup_wizard_step = $current_settings[ 'setup_wizard_step' ];
  9215. }
  9216. $setup_complete = false;
  9217. $setup_complete_missing = true;
  9218. if ( isset( $current_settings[ 'setup_complete' ] ) ) {
  9219. $setup_complete = $current_settings[ 'setup_complete' ];
  9220. $setup_complete_missing = false;
  9221. }
  9222. //Skip checks during first setup wizard
  9223. if(($setup_wizard_step!==false && $setup_wizard_step < 4) || (!$setup_complete_missing && $setup_complete===false && $setup_wizard_step==4 )) return true;
  9224. $default_language = false;
  9225. $default_language_missing = true;
  9226. if ( isset( $current_settings[ 'default_language' ] ) ) {
  9227. $default_language = $current_settings[ 'default_language' ];
  9228. $default_language_missing = false;
  9229. }
  9230. $active_languages_sql = "SELECT * FROM " . $wpdb->prefix . 'icl_languages WHERE active=%d';
  9231. $active_languages_prepared = $wpdb->prepare( $active_languages_sql, array(1) );
  9232. $active_languages = $wpdb->get_results( $active_languages_prepared );
  9233. $existing_translations_sql = "SELECT count(*) FROM " . $wpdb->prefix . 'icl_translations';
  9234. $existing_translations = $wpdb->get_var( $existing_translations_sql );
  9235. $show_notice = false;
  9236. $message = '';
  9237. if ( (!$setup_complete || !$default_language) && $existing_translations ) {
  9238. $message .= '<p>';
  9239. $message .= __( 'Your WPML settings seem to be corrupted. To avoid corrupting your existing data, we have hidden WPML from this site.', 'sitepress' );
  9240. $message .= '</p>';
  9241. $message .= '<p>';
  9242. $message .= __( 'If this is the first time you install WPML on this site, you may have faced a database or script connection drop, that caused settings to be not completely store.', 'sitepress' );
  9243. $message .= __( 'In this case, you can click on the <strong>Reset Settings</strong> button: this will reset WPML settings and any language translation information, allowing you to restart the wizard.', 'sitepress' );
  9244. $message .= '</p>';
  9245. $message .= '<p>';
  9246. $message .= sprintf( __( 'If you have just upgraded WPML or after starting over you keep getting this message, please contact the <a href="%s">support forum</a> as soon as possible, in order to provide you with a fix to this issue.', 'sitepress' ), 'https://wpml.org/forums/' );
  9247. $message .= '</p>';
  9248. $message .= '<p>';
  9249. $confirm_message = _x('Are you sure you want to reset WPML Settings?', 'Reset WPML settings', 'sitepress');
  9250. $confirm_message .= ' ';
  9251. $confirm_message .= _x('This will also empty translation information (if any).', 'Reset WPML settings', 'sitepress');
  9252. $message .= '<a href="?icl_reset_settings=1&debug_action=reset_wpml_settings&nonce=' . wp_create_nonce( 'reset_wpml_settings' ) . '" class="button" onclick="return window.confirm(\'' . $confirm_message . '\');" >' . __('Reset Settings','sitepress') . '</a>';
  9253. $message .= '&nbsp;';
  9254. $message .= '&nbsp;';
  9255. $message .= '&nbsp;';
  9256. $message .= '<a href="https://wpml.org/forums/" class="button">' . __('Contact Support','sitepress') . '</a>';
  9257. $message .= '</p>';
  9258. $message .= '<p>';
  9259. $message .= __( 'Additional details for the support team (there is no need to copy it, as the support team will be able to see it once logged in):', 'sitepress' );
  9260. $message .= '</p>';
  9261. $message .= '<p><textarea rows="10" style="width:100%;display:block;" onclick="this.focus();this.select();" readonly="readonly">';
  9262. $message .= str_repeat( '=', 50 );
  9263. $wpml_plugins_list = SitePress::get_installed_plugins();
  9264. foreach ( $wpml_plugins_list as $name => $plugin_data ) {
  9265. $plugin_name = $name;
  9266. $file = $plugin_data['file'];
  9267. $message .= PHP_EOL . $plugin_name;
  9268. $message .= ' ' . (isset( $plugin_data['plugin']['Version'] ) ? $plugin_data['plugin']['Version'] : __( 'Version n/a', 'sitepress' ));
  9269. $message .= ' => ';
  9270. if ( empty( $plugin_data['plugin'] ) ) {
  9271. $message .= 'Not installed';
  9272. } else {
  9273. $message .= 'Installed';
  9274. }
  9275. $message .= '/';
  9276. $message .= isset( $file ) && is_plugin_active( $file ) ? 'Active' : 'Not Active';
  9277. }
  9278. $message .= PHP_EOL . str_repeat( '-', 50 );
  9279. $message .= PHP_EOL . 'icl_translations count: ' . ( $existing_translations ? $existing_translations : '0' );
  9280. $message .= PHP_EOL . 'setup_complete: ' . ( $setup_complete ? 'true' : 'false' );
  9281. $message .= PHP_EOL . 'setup_complete missing: ' . ( $setup_complete_missing ? 'true' : 'false' );
  9282. $message .= PHP_EOL . 'default_language: ' . ( $default_language ? $default_language : '""' );
  9283. $message .= PHP_EOL . 'default_language_missing: ' . ( $default_language_missing ? 'true' : 'false' );
  9284. $message .= PHP_EOL . PHP_EOL . 'active_languages: ' . PHP_EOL . print_r( $active_languages, true );
  9285. $message .= PHP_EOL . PHP_EOL . 'icl_sitepress_settings (serialized): ' . PHP_EOL . serialize( $current_settings );
  9286. $message .= PHP_EOL . PHP_EOL . 'icl_sitepress_settings (unserialized): ' . PHP_EOL . print_r( $current_settings, true );
  9287. $message .= PHP_EOL . str_repeat( '=', 50 );
  9288. $message .= '</textarea></p>';
  9289. $show_notice = true;
  9290. }
  9291. // ICL_AdminNotifier::removeMessage( 'check_settings_integrity' );
  9292. ICL_AdminNotifier::removeMessage( 'check_settings_integrity_corrupted' );
  9293. if ( $show_notice ) {
  9294. ICL_AdminNotifier::addMessage( 'check_settings_integrity_corrupted', $message, 'error', false, false, false, 'check_settings_integrity', true );
  9295. ICL_AdminNotifier::displayMessages( 'check_settings_integrity' );
  9296. }
  9297. $result = !$show_notice;
  9298. return $result;
  9299. }
  9300. /**
  9301. * @param int $limit
  9302. * @param bool $provide_object
  9303. * @param bool $ignore_args
  9304. *
  9305. * @return array
  9306. */
  9307. public function get_backtrace($limit = 0, $provide_object = false, $ignore_args = true) {
  9308. $options = false;
  9309. if ( version_compare( phpversion(), '5.3.6' ) < 0 ) {
  9310. // Before 5.3.6, the only values recognized are TRUE or FALSE,
  9311. // which are the same as setting or not setting the DEBUG_BACKTRACE_PROVIDE_OBJECT option respectively.
  9312. $options = $provide_object;
  9313. } else {
  9314. // As of 5.3.6, 'options' parameter is a bitmask for the following options:
  9315. if ( $provide_object )
  9316. $options |= DEBUG_BACKTRACE_PROVIDE_OBJECT;
  9317. if ( $ignore_args )
  9318. $options |= DEBUG_BACKTRACE_IGNORE_ARGS;
  9319. }
  9320. if ( version_compare( phpversion(), '5.4.0' ) >= 0 ) {
  9321. $actual_limit = $limit == 0 ? 0 : $limit + 1;
  9322. $debug_backtrace = debug_backtrace( $options, $actual_limit ); //add one item to include the current frame
  9323. } elseif ( version_compare( phpversion(), '5.2.4' ) >= 0 ) {
  9324. //@link https://core.trac.wordpress.org/ticket/20953
  9325. $debug_backtrace = debug_backtrace();
  9326. } else {
  9327. $debug_backtrace = debug_backtrace( $options );
  9328. }
  9329. //Remove the current frame
  9330. if($debug_backtrace) {
  9331. array_shift($debug_backtrace);
  9332. }
  9333. return $debug_backtrace;
  9334. }
  9335. /**
  9336. * Translate the value returned by 'option_{taxonomy}_children' and store it in cache
  9337. *
  9338. * @param array $original_value
  9339. * @param bool|string $current_language
  9340. * @param bool|string $taxonomy
  9341. *
  9342. * @return array
  9343. */
  9344. function option_taxonomy_children( $original_value, $current_language = false, $taxonomy = false ) {
  9345. if(!is_array($original_value) || count($original_value)==0) return $original_value;
  9346. $current_language = !$current_language ? $this->get_current_language() : $current_language;
  9347. $default_language = $this->get_default_language();
  9348. if ( $current_language == $default_language ) {
  9349. return $original_value;
  9350. }
  9351. $cache_key_array[ ] = $current_language;
  9352. $cache_key_array[ ] = $default_language;
  9353. $cache_key_array[ ] = $original_value;
  9354. $cache_key = md5( serialize( $cache_key_array ) );
  9355. $cache_group = 'translate_taxonomy_children';
  9356. $cache_found = false;
  9357. $result = wp_cache_get( $cache_key, $cache_group, false, $cache_found );
  9358. if ( $cache_found ) {
  9359. return $result;
  9360. }
  9361. $debug_backtrace = $this->get_backtrace( 4, false, false );
  9362. //Find the taxonomy name
  9363. if ( !$taxonomy && isset( $debug_backtrace[ 3 ] ) && isset( $debug_backtrace[ 3 ][ 'args' ] ) ) {
  9364. $option_name = $debug_backtrace[ 3 ][ 'args' ][ 0 ];
  9365. $taxonomies = explode( '_', $option_name );
  9366. $taxonomy = $taxonomies[ 0 ];
  9367. }
  9368. $translated_children = array();
  9369. if ( $taxonomy && is_array( $original_value ) ) {
  9370. foreach ( $original_value as $children_term_ids ) {
  9371. foreach ( $children_term_ids as $child_term_id ) {
  9372. $translated_child_term_id = icl_object_id( $child_term_id, $taxonomy, false, $current_language );
  9373. if ( $translated_child_term_id ) {
  9374. $translated_parent_term_id = wp_get_term_taxonomy_parent_id( $translated_child_term_id, $taxonomy );
  9375. if ( $translated_parent_term_id ) {
  9376. if ( ! isset( $translated_children[ $translated_parent_term_id ] ) ) {
  9377. $translated_children[ $translated_parent_term_id ] = array();
  9378. }
  9379. $translated_children[ $translated_parent_term_id ][ ] = $translated_child_term_id;
  9380. }
  9381. }
  9382. }
  9383. }
  9384. }
  9385. wp_cache_set( $cache_key, $translated_children, $cache_group );
  9386. return $translated_children;
  9387. }
  9388. function pre_update_option_taxonomy_children($value, $old_value) {
  9389. $current_language = $this->get_current_language();
  9390. $default_language = $this->get_default_language();
  9391. if ( $current_language == $default_language ) {
  9392. return $value;
  9393. }
  9394. $cache_key_array[ ] = $current_language;
  9395. $cache_key_array[ ] = $default_language;
  9396. $cache_key_array[ ] = $value;
  9397. $cache_key_array[ ] = $old_value;
  9398. $cache_key = md5( serialize( $cache_key_array ) );
  9399. $cache_group = 'pre_update_option_taxonomy_children';
  9400. $cache_found = false;
  9401. $result = wp_cache_get( $cache_key, $cache_group, false, $cache_found );
  9402. if ( $cache_found ) {
  9403. return $result;
  9404. }
  9405. $debug_backtrace = $this->get_backtrace( 4, false, false );
  9406. $taxonomy = false;
  9407. //Find the taxonomy name
  9408. if ( isset( $debug_backtrace[ 3 ] ) && isset( $debug_backtrace[ 3 ][ 'args' ] ) ) {
  9409. $option_name = $debug_backtrace[ 3 ][ 'args' ][ 0 ];
  9410. $taxonomies = explode( '_', $option_name );
  9411. $taxonomy = $taxonomies[ 0 ];
  9412. }
  9413. if($taxonomy) {
  9414. remove_filter("option_{$taxonomy}_children", array($this, 'option_taxonomy_children'), 10 );
  9415. remove_filter("pre_update_option_{$taxonomy}_children", array($this, 'pre_update_option_taxonomy_children'), 10 );
  9416. $new_value = get_option("{$taxonomy}_children");
  9417. add_filter("option_{$taxonomy}_children", array($this, 'option_taxonomy_children'), 10 );
  9418. add_filter("pre_update_option_{$taxonomy}_children", array($this, 'pre_update_option_taxonomy_children'), 10, 2 );
  9419. return $new_value;
  9420. }
  9421. return $value;
  9422. }
  9423. /**
  9424. * @param int|array $terms_ids
  9425. * @param $taxonomy
  9426. */
  9427. public function update_terms_relationship_cache( $terms_ids, $taxonomy ) {
  9428. remove_filter( 'get_terms_args', array( $this, 'get_terms_args_filter' ) );
  9429. remove_filter( 'terms_clauses', array( $this, 'terms_clauses' ), 10 );
  9430. remove_filter( 'list_terms_exclusions', array( $this, 'exclude_other_terms' ), 1 );
  9431. clean_term_cache( $terms_ids, $taxonomy );
  9432. add_filter( 'get_terms_args', array( $this, 'get_terms_args_filter' ) );
  9433. // filters terms by language
  9434. add_filter( 'terms_clauses', array( $this, 'terms_clauses' ), 10, 4 );
  9435. add_filter( 'list_terms_exclusions', array( $this, 'exclude_other_terms' ), 1, 2 );
  9436. }
  9437. /**
  9438. * Used as filter for wordpress core function url_to_postid()
  9439. *
  9440. * @global AbsoluteLinks $absolute_links_object
  9441. * @param string $url URL to filter
  9442. * @return string URL changed into format ...?p={ID} or original
  9443. */
  9444. function url_to_postid($url) {
  9445. if ((strpos($url, 'wp-login.php') !== false)) {
  9446. return $url;
  9447. } else if ( strpos($url, '/wp-admin/') !== false ) {
  9448. return $url;
  9449. } else if ( strpos($url, '/wp-content/') !== false ) {
  9450. return $url;
  9451. }
  9452. $is_language_in_domain = false; // if language negotiation type as lang. in domain
  9453. $is_translated_domain = false; // if this url is in secondary language domain
  9454. // for 'diffrent domain per language' we need to switch_lang according to domain of parsed $url
  9455. if (2 == $this->settings['language_negotiation_type'] && isset($this->settings['language_domains'])) {
  9456. $is_language_in_domain = true;
  9457. // if url domain fits to one of secondary language domains
  9458. // switch sitepress language to this
  9459. // but save current language context in $current_language, we will have to switch to this back
  9460. foreach ($this->settings['language_domains'] as $code => $domain) {
  9461. if ( strpos($url, $domain) === 0 ) {
  9462. $is_translated_domain = true;
  9463. $current_language = $this->get_current_language();
  9464. $this->switch_lang($code);
  9465. $url = str_replace($domain, site_url(), $url);
  9466. break;
  9467. }
  9468. }
  9469. // if it is url in original domain
  9470. // switch sitepress language to default language
  9471. // but save current language context in $current_language, we will have to switch to this back
  9472. if (!$is_translated_domain) {
  9473. $current_language = $this->get_current_language();
  9474. $default_language = $this->get_default_language();
  9475. $this->switch_lang($default_language);
  9476. }
  9477. }
  9478. // we will use AbsoluteLinks::_process_generic_text, so make sure that
  9479. // we have this object here
  9480. global $absolute_links_object;
  9481. if (!isset($absolute_links_object) || !is_a($absolute_links_object, 'AbsoluteLinks') || $is_language_in_domain ) {
  9482. require_once ICL_PLUGIN_PATH . '/inc/absolute-links/absolute-links.class.php';
  9483. $absolute_links_object = new AbsoluteLinks();
  9484. }
  9485. // in next steps we will have to compare processed url with original,
  9486. // so we need to save original
  9487. $original_url = $url;
  9488. // we also need site_url for comparisions
  9489. $site_url = site_url();
  9490. // _process_generic_text will change slug urls into ?p=1 or ?cpt-slug=cpt-title
  9491. // but this function operates not on clean url but on html <a> element
  9492. // we need to change temporary url into html, pass to this function and
  9493. // extract url from returned html
  9494. $html = '<a href="'.$url.'">removeit</a>';
  9495. $alp_broken_links = array();
  9496. remove_filter('url_to_postid', array($this, 'url_to_postid'));
  9497. $html = $absolute_links_object->_process_generic_text($html, $alp_broken_links);
  9498. add_filter('url_to_postid', array($this, 'url_to_postid'));
  9499. $url = str_replace(array('<a href="', '">removeit</a>'), array('', ''), $html);
  9500. // for 'diffrent domain per language', switch language back. now we can do this
  9501. if ($is_language_in_domain) {
  9502. $this->switch_lang($current_language);
  9503. }
  9504. // if this is not url to external site
  9505. if ( 0 === strpos($original_url, $site_url)) {
  9506. // if this is url like ...?cpt-rewrite-slug=cpt-title
  9507. // change it into ...?p=11
  9508. $url2 = $this->cpt_url_to_id_url($url, $original_url);
  9509. if ($url2 == $url && $original_url != $url) { // if it was not a case with ?cpt-slug=cpt-title
  9510. // if this is translated post and it has the same slug as original,
  9511. // _process_generic_text returns the same ID for both
  9512. // lets check if it is this case and replace ID in returned url
  9513. $url = $this->maybe_adjust_url($url, $original_url);
  9514. } else { // yes! it was not a case with ?cpt-slug=cpt-title
  9515. $url = $url2;
  9516. }
  9517. }
  9518. return $url;
  9519. }
  9520. /**
  9521. * Check if $url is in format ...?cpt-slug=cpt-title and change into ...?p={ID}
  9522. *
  9523. *
  9524. * @param string $url URL, probably in format ?cpt-slug=cpt-title
  9525. * @param string $original_url URL in original format (probably with permalink)
  9526. * @return string URL, if $url was in expected format ?cpt-slug format, url is now changed into ?p={ID}, otherwise, returns $url as it was passed in parameter
  9527. */
  9528. function cpt_url_to_id_url($url, $original_url) {
  9529. $parsed_url = parse_url($url);
  9530. if (!isset($parsed_url['query'])) {
  9531. return $url;
  9532. }
  9533. $query = $parsed_url['query'];
  9534. parse_str($query, $vars);
  9535. $args = array(
  9536. 'public' => true,
  9537. '_builtin' => false
  9538. );
  9539. $post_types = get_post_types($args, 'objects');
  9540. foreach ($post_types as $name => $attrs) {
  9541. if ( isset( $vars[ $attrs->rewrite['slug'] ] ) ) {
  9542. $post_type = $name;
  9543. $post_slug = $vars[ $attrs->rewrite['slug'] ];
  9544. break;
  9545. }
  9546. }
  9547. if (!isset($post_type, $post_slug)) {
  9548. return $url;
  9549. }
  9550. $args = array(
  9551. 'name' => $post_slug,
  9552. 'post_type' => $post_type
  9553. );
  9554. $post = new WP_Query($args);
  9555. if (!isset($post->post)) {
  9556. return $url;
  9557. }
  9558. $id = $post->post->ID;
  9559. $post_language = $this->get_language_for_element($id, 'post_' . $post_type);
  9560. $url_language = $this->get_language_from_url($original_url);
  9561. if ($post_language != $url_language) {
  9562. $trid = $this->get_element_trid( $id, 'post_' . $post_type );
  9563. $translations = $this->get_element_translations( $trid, 'post_' . $post_type );
  9564. if (isset($translations[$url_language])) {
  9565. $translation = $translations[$url_language];
  9566. if (isset($translation->element_id)) {
  9567. $nvars['p'] = $translation->element_id;
  9568. }
  9569. }
  9570. } else {
  9571. $nvars['p'] = $id;
  9572. }
  9573. $new_query = http_build_query($nvars);
  9574. $url = str_replace($query, $new_query, $url);
  9575. return $url;
  9576. }
  9577. /**
  9578. * Fix sticky link url to have ID of translated post (used in case both translations have same slug)
  9579. *
  9580. * @param string $url - url in sticky link form
  9581. * @param string $original_url - url in permalink form
  9582. * @return string - url in sticky link form to correct translation
  9583. */
  9584. private function maybe_adjust_url($url, $original_url) {
  9585. $url_language = $this->get_language_from_url($original_url);
  9586. $parsed_url = parse_url($url);
  9587. $query = $parsed_url['query'];
  9588. parse_str($query, $vars);
  9589. if (isset($vars['page_id'])) {
  9590. $inurl = 'page_id';
  9591. $post_id = $vars['page_id'];
  9592. } elseif (isset($vars['p'])) {
  9593. $inurl = 'p';
  9594. $post_id = $vars['p'];
  9595. }
  9596. if (isset($post_id)) {
  9597. $post_type = get_post_type($post_id);
  9598. $post_language = $this->get_language_for_element($post_id, 'post_' . $post_type);
  9599. if ($post_language != $url_language) {
  9600. $trid = $this->get_element_trid( $post_id, 'post_' . $post_type );
  9601. $translations = $this->get_element_translations( $trid, 'post_' . $post_type );
  9602. if (isset($translations[$url_language])) {
  9603. $translation = $translations[$url_language];
  9604. if (isset($translation->element_id)) {
  9605. $vars[$inurl] = $translation->element_id;
  9606. $new_query = http_build_query($vars);
  9607. $url = str_replace($query, $new_query, $url);
  9608. }
  9609. }
  9610. }
  9611. }
  9612. return $url;
  9613. }
  9614. /**
  9615. * Find language of document based on given permalink
  9616. *
  9617. * @param string $url Local url in permalink form
  9618. * @return string two letters language code
  9619. */
  9620. function get_language_from_url($url) {
  9621. static $languages;
  9622. if (isset($languages[$url])) {
  9623. return $languages[$url];
  9624. }
  9625. $site_url = site_url();
  9626. if (1 == $this->settings['language_negotiation_type']) {
  9627. $url_path = ltrim(
  9628. str_replace($site_url, "", $url),
  9629. "/");
  9630. $fragments = explode("/", $url_path);
  9631. $fragment = $fragments[0];
  9632. if (isset($this->active_languages[$fragment])) {
  9633. $languages[$url] = $fragment;
  9634. return $fragment;
  9635. } else {
  9636. $languages[$url] = $this->get_default_language();
  9637. return $this->get_default_language();
  9638. }
  9639. } else if ( 2 == $this->settings['language_negotiation_type'] ) {
  9640. if ( isset($this->settings['language_domains'])) {
  9641. $is_translated_domain = false;
  9642. foreach ($this->settings['language_domains'] as $code => $domain) {
  9643. if ( strpos($url, $domain) === 0 ) {
  9644. $is_translated_domain = true;
  9645. $languages[$url] = $code;
  9646. return $code;
  9647. }
  9648. }
  9649. }
  9650. $languages[$url] = $this->get_current_language();
  9651. return $this->get_current_language();
  9652. } else if (3 == $this->settings['language_negotiation_type']) {
  9653. $url_query = parse_url($url, PHP_URL_QUERY);
  9654. if (isset($url_query)) {
  9655. parse_str($url_query, $vars);
  9656. if (isset($vars['lang']) && isset($this->active_languages[ $vars['lang'] ])) {
  9657. $languages[$url] = $vars['lang'];
  9658. return $vars['lang'];
  9659. }
  9660. }
  9661. $languages[$url] = $this->get_default_language();
  9662. return $this->get_default_language();
  9663. }
  9664. }
  9665. function update_wpml_config_index_event(){
  9666. $wp_http_class = new WP_Http();
  9667. $response = $wp_http_class->get( ICL_REMOTE_WPML_CONFIG_FILES_INDEX . 'wpml-config/config-index.json');
  9668. if(!is_wp_error($response) && $response['response']['code'] == 200){
  9669. $arr = json_decode($response['body']);
  9670. if( isset( $arr->plugins ) && isset( $arr->themes ) ){
  9671. update_option('wpml_config_index',$arr);
  9672. update_option('wpml_config_index_updated',time());
  9673. $config_files_arr = maybe_unserialize(get_option('wpml_config_files_arr'));
  9674. if($config_files_arr){
  9675. $config_files_themes_arr = $config_files_arr->themes;
  9676. $config_files_plugins_arr = $config_files_arr->plugins;
  9677. }else{
  9678. $config_files_themes_arr = array();
  9679. $config_files_plugins_arr = array();
  9680. }
  9681. $wp_http_class = new WP_Http();
  9682. $theme_data = wp_get_theme();
  9683. foreach($arr->themes as $theme){
  9684. if( $theme_data->get( 'Name' ) == $theme->name && ( !isset( $config_files_themes_arr[$theme->name] ) || md5( $config_files_themes_arr[$theme->name] ) != $theme->hash ) ){
  9685. $response = $wp_http_class->get(ICL_REMOTE_WPML_CONFIG_FILES_INDEX . $theme->path);
  9686. if($response['response']['code'] == 200){
  9687. $config_files_themes_arr[$theme->name] = $response['body'];
  9688. }
  9689. }
  9690. }
  9691. if ( ! function_exists( 'get_plugins' ) ) {
  9692. require_once ABSPATH . 'wp-admin/includes/plugin.php';
  9693. }
  9694. $active_plugins = get_plugins();
  9695. foreach( $active_plugins as $active_plugin ){
  9696. $active_plugins_names[] = $active_plugin['Name'];
  9697. }
  9698. foreach($arr->plugins as $plugin){
  9699. if( in_array($plugin->name,$active_plugins_names) && ( !isset( $config_files_plugins_arr[$plugin->name] ) || md5( $config_files_plugins_arr[$plugin->name] ) != $plugin->hash ) ){
  9700. $response = $wp_http_class->get(ICL_REMOTE_WPML_CONFIG_FILES_INDEX . $plugin->path);
  9701. if(!is_wp_error($response) &&$response['response']['code'] == 200){
  9702. $config_files_plugins_arr[$plugin->name] = $response['body'];
  9703. }
  9704. }
  9705. }
  9706. if ( ! isset( $config_files_arr ) || ! $config_files_arr ) {
  9707. $config_files_arr = new stdClass();
  9708. }
  9709. $config_files_arr->themes = $config_files_themes_arr;
  9710. $config_files_arr->plugins = $config_files_plugins_arr;
  9711. update_option('wpml_config_files_arr',$config_files_arr);
  9712. return true;
  9713. }
  9714. }
  9715. return false;
  9716. }
  9717. function update_wpml_config_index_event_ajax(){
  9718. if($this->update_wpml_config_index_event()){
  9719. echo date('F j, Y H:i a', time());
  9720. }
  9721. die;
  9722. }
  9723. function update_index_screen(){
  9724. return include ICL_PLUGIN_PATH . '/menu/theme-plugins-compatibility.php';
  9725. }
  9726. /**
  9727. * Filter to add language field to WordPress search form
  9728. *
  9729. * @param string $form HTML code of search for before filtering
  9730. * @return string HTML code of search form
  9731. */
  9732. function get_search_form_filter($form) {
  9733. if ( strpos($form, wpml_get_language_input_field() ) === false ) {
  9734. $form = str_replace("</form>", wpml_get_language_input_field() . "</form>", $form);
  9735. }
  9736. return $form;
  9737. }
  9738. }