PageRenderTime 51ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/wp-content/plugins/wpml-string-translation/inc/functions.php

https://bitbucket.org/dkrzos/phc
PHP | 2619 lines | 2160 code | 385 blank | 74 comment | 448 complexity | 6d9bc3d38e6cd5a7760629a3a6ab8190 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. $icl_st_string_translation_statuses = array(
  3. ICL_STRING_TRANSLATION_COMPLETE => __('Translation complete','wpml-string-translation'),
  4. ICL_STRING_TRANSLATION_PARTIAL => __('Partial translation','wpml-string-translation'),
  5. ICL_STRING_TRANSLATION_NEEDS_UPDATE => __('Translation needs update','wpml-string-translation'),
  6. ICL_STRING_TRANSLATION_NOT_TRANSLATED => __('Not translated','wpml-string-translation'),
  7. ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR => __('Waiting for translator','wpml-string-translation')
  8. );
  9. add_action('plugins_loaded', 'icl_st_init');
  10. add_action('icl_update_active_languages', 'icl_update_string_status_all');
  11. add_action('update_option_blogname', 'icl_st_update_blogname_actions',5,2);
  12. add_action('update_option_blogdescription', 'icl_st_update_blogdescription_actions',5,2);
  13. if(!defined('XMLRPC')){
  14. // called separately for XMLRPC post saves
  15. add_action('save_post', 'icl_st_fix_links_in_strings', 19);
  16. }
  17. //add_filter('xmlrpc_methods','icl_add_custom_xmlrpc_methods');
  18. function icl_st_init(){
  19. global $sitepress_settings, $sitepress, $wpdb, $icl_st_err_str;
  20. if(isset($_GET['icl_action']) && $_GET['icl_action'] == 'view_string_in_page'){
  21. icl_st_string_in_page($_GET['string_id']);
  22. exit;
  23. }
  24. if(isset($_GET['icl_action']) && $_GET['icl_action'] == 'view_string_in_source'){
  25. icl_st_string_in_source($_GET['string_id']);
  26. exit;
  27. }
  28. if ( get_magic_quotes_gpc() && isset($_GET['page']) && $_GET['page'] == WPML_ST_FOLDER . '/menu/string-translation.php'){
  29. $_POST = stripslashes_deep( $_POST );
  30. }
  31. if(!isset($sitepress_settings['existing_content_language_verified']) || !$sitepress_settings['existing_content_language_verified']){
  32. return;
  33. }
  34. if(!isset($sitepress_settings['st']['sw'])){
  35. $sitepress_settings['st']['sw'] = array(); //no settings for now
  36. $sitepress->save_settings($sitepress_settings);
  37. $init_all = true;
  38. }
  39. if(!isset($sitepress_settings['st']['strings_per_page'])){
  40. $sitepress_settings['st']['strings_per_page'] = 10;
  41. $sitepress->save_settings($sitepress_settings);
  42. }elseif(isset($_GET['strings_per_page']) && $_GET['strings_per_page'] > 0){
  43. $sitepress_settings['st']['strings_per_page'] = $_GET['strings_per_page'];
  44. $sitepress->save_settings($sitepress_settings);
  45. }
  46. if(!isset($sitepress_settings['st']['icl_st_auto_reg'])){
  47. $sitepress_settings['st']['icl_st_auto_reg'] = 'disabled';
  48. $sitepress->save_settings($sitepress_settings);
  49. }
  50. if(empty($sitepress_settings['st']['strings_language'])){
  51. $iclsettings['st']['strings_language'] = $sitepress_settings['st']['strings_language'] = $sitepress->get_default_language();
  52. $sitepress->save_settings($iclsettings);
  53. }
  54. if(!isset($sitepress_settings['st']['translated-users'])) $sitepress_settings['st']['translated-users'] = array();
  55. if((isset($_POST['iclt_st_sw_save']) && wp_verify_nonce($_POST['_wpnonce'], 'icl_sw_form')) || isset($init_all)){
  56. if(isset($init_all)){
  57. icl_register_string('WP',__('Blog Title','wpml-string-translation'), get_option('blogname'));
  58. icl_register_string('WP',__('Tagline', 'wpml-string-translation'), get_option('blogdescription'));
  59. __icl_st_init_register_widget_titles();
  60. // create a list of active widgets
  61. $active_text_widgets = array();
  62. $widgets = (array)get_option('sidebars_widgets');
  63. foreach($widgets as $k=>$w){
  64. if('wp_inactive_widgets' != $k && $k != 'array_version'){
  65. foreach($widgets[$k] as $v){
  66. if(preg_match('#text-([0-9]+)#i',$v, $matches)){
  67. $active_text_widgets[] = $matches[1];
  68. }
  69. }
  70. }
  71. }
  72. $widget_text = get_option('widget_text');
  73. if(is_array($widget_text)){
  74. foreach($widget_text as $k=>$w){
  75. if(!empty($w) && isset($w['title']) && in_array($k, $active_text_widgets)){
  76. icl_register_string('Widgets', 'widget body - ' . md5(apply_filters('widget_text',$w['text'])), apply_filters('widget_text',$w['text']));
  77. }
  78. }
  79. }
  80. }
  81. if(isset($_POST['iclt_st_sw_save'])){
  82. $updat_string_statuses = false;
  83. $sitepress_settings['st']['sw'] = $_POST['icl_st_sw'];
  84. if($sitepress_settings['st']['strings_language'] != $_POST['icl_st_sw']['strings_language']){
  85. $updat_string_statuses = true;
  86. }
  87. $sitepress_settings['st']['strings_language'] = $_POST['icl_st_sw']['strings_language'];
  88. $sitepress->save_settings($sitepress_settings);
  89. if($updat_string_statuses){
  90. icl_update_string_status_all();
  91. }
  92. //register author strings
  93. if(!empty($sitepress_settings['st']['translated-users'])){
  94. icl_st_register_user_strings_all();
  95. }
  96. wp_redirect($_SERVER['REQUEST_URI'].'&updated=true');
  97. }
  98. }
  99. // handle po file upload
  100. if(isset($_POST['icl_po_upload']) && wp_verify_nonce($_POST['_wpnonce'], 'icl_po_form')){
  101. global $icl_st_po_strings;
  102. if($_FILES['icl_po_file']['size']==0){
  103. $icl_st_err_str = __('File upload error', 'wpml-string-translation');
  104. }else{
  105. $lines = file($_FILES['icl_po_file']['tmp_name']);
  106. $icl_st_po_strings = array();
  107. $fuzzy = 0;
  108. for($k = 0; $k < count($lines); $k++){
  109. if(0 === strpos($lines[$k], '#, fuzzy')){
  110. $fuzzy = 1;
  111. $k++;
  112. }
  113. $int = preg_match('#msgid "(.+)"#im',trim($lines[$k]), $matches);
  114. if($int){
  115. $string = str_replace('\"','"', $matches[1]);
  116. $int = preg_match('#msgstr "(.+)"#im',trim($lines[$k+1]),$matches);
  117. if($int){
  118. $translation = str_replace('\"','"',$matches[1]);
  119. }else{
  120. $translation = "";
  121. }
  122. $string_exists = $wpdb->get_var("
  123. SELECT id FROM {$wpdb->prefix}icl_strings
  124. WHERE context='".$wpdb->escape($_POST['icl_st_i_context_new']?$_POST['icl_st_i_context_new']:$_POST['icl_st_i_context'])."'
  125. AND name='".md5($string)."'");
  126. $icl_st_po_strings[] = array(
  127. 'string' => $string,
  128. 'translation' => $translation,
  129. 'fuzzy' => $fuzzy,
  130. 'exists' => $string_exists
  131. );
  132. $k++;
  133. }
  134. if(!trim($lines[$k])){
  135. $fuzzy = 0;
  136. }
  137. }
  138. if(empty($icl_st_po_strings)){
  139. $icl_st_err_str = __('No string found', 'wpml-string-translation');
  140. }
  141. }
  142. }
  143. elseif(isset($_POST['action']) && 'icl_st_save_strings' == $_POST['action']){
  144. $arr = array_intersect_key($_POST['icl_strings'], array_flip($_POST['icl_strings_selected']));
  145. //$arr = array_map('html_entity_decode', $arr);
  146. if(isset($_POST['icl_st_po_language'])){
  147. $arr_t = array_intersect_key($_POST['icl_translations'], array_flip($_POST['icl_strings_selected']));
  148. $arr_f = array_intersect_key($_POST['icl_fuzzy'], array_flip($_POST['icl_strings_selected']));
  149. //$arr_t = array_map('html_entity_decode', $arr_t);
  150. }
  151. // see if the strings are already registered and have names
  152. // case of adding translation
  153. $res = $wpdb->get_results("
  154. SELECT value, name
  155. FROM {$wpdb->prefix}icl_strings
  156. WHERE context = '". $wpdb->escape($_POST['icl_st_domain_name']) ."' AND value IN ('".join("','", array_map('mysql_real_escape_string', $arr))."')
  157. ");
  158. if(!empty($res)){
  159. foreach($res as $r){
  160. $map[$r->value] = $r->name;
  161. }
  162. }
  163. foreach($arr as $k=>$string){
  164. if(isset($map[$string])){
  165. $name = $map[$string];
  166. }else{
  167. $name = md5($string);
  168. }
  169. $string_id = icl_register_string($_POST['icl_st_domain_name'], $name, $string);
  170. if($string_id && isset($_POST['icl_st_po_language'])){
  171. if($arr_t[$k] != ""){
  172. if($arr_f[$k]){
  173. $_status = ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  174. }else{
  175. $_status = ICL_STRING_TRANSLATION_COMPLETE;
  176. }
  177. icl_add_string_translation($string_id, $_POST['icl_st_po_language'], $arr_t[$k], $_status);
  178. icl_update_string_status($string_id);
  179. }
  180. }
  181. }
  182. }
  183. //handle po export
  184. if(isset($_POST['icl_st_pie_e']) && wp_verify_nonce($_POST['_wpnonce'], 'icl_po_export')){
  185. //force some filters
  186. if(isset($_GET['status'])) unset($_GET['status']);
  187. $_GET['show_results']='all';
  188. if($_POST['icl_st_e_context']){
  189. $_GET['context'] = $_POST['icl_st_e_context'];
  190. }
  191. $_GET['translation_language'] = $_POST['icl_st_e_language'];
  192. $strings = icl_get_string_translations();
  193. if(!empty($strings)){
  194. $po = icl_st_generate_po_file($strings, !isset($_POST['icl_st_pe_translations']));
  195. }else{
  196. $po = "";
  197. }
  198. if(!isset($_POST['icl_st_pe_translations'])){
  199. $popot = 'pot';
  200. $poname = $_POST['icl_st_e_context'] ? urlencode($_POST['icl_st_e_context']) : 'all_context';
  201. }else{
  202. $popot = 'po';
  203. $poname = $_GET['translation_language'];
  204. }
  205. header("Content-Type: application/force-download");
  206. header("Content-Type: application/octet-stream");
  207. header("Content-Type: application/download");
  208. header("Content-Disposition: attachment; filename=".$poname.'.'.$popot.";");
  209. header("Content-Length: ". strlen($po));
  210. echo $po;
  211. exit(0);
  212. }
  213. // handle string translation request
  214. elseif(isset($_POST['icl_st_action']) && $_POST['icl_st_action'] == 'send_strings'){
  215. if($_POST['iclnonce'] == wp_create_nonce('icl-string-translation')){
  216. $_POST = stripslashes_deep($_POST);
  217. $services = $_POST['service'];
  218. $string_ids = explode(',', $_POST['strings']);
  219. $translate_to = array();
  220. foreach($_POST['translate_to'] as $lang_to=>$one){
  221. if(isset($services[$lang_to])){
  222. $translate_to[$lang_to] = $services[$lang_to];
  223. }
  224. }
  225. if(!empty($translate_to)){
  226. icl_translation_send_strings($string_ids, $translate_to);
  227. }
  228. }
  229. }
  230. // hook into blog title and tag line
  231. add_filter('option_blogname', 'icl_sw_filters_blogname');
  232. add_filter('option_blogdescription', 'icl_sw_filters_blogdescription');
  233. add_filter('widget_title', 'icl_sw_filters_widget_title');
  234. add_filter('widget_text', 'icl_sw_filters_widget_text');
  235. if(isset($sitepress_settings['theme_localization_type']) && $sitepress_settings['theme_localization_type']==1){
  236. add_filter('gettext', 'icl_sw_filters_gettext', 9, 3);
  237. add_filter('gettext_with_context', 'icl_sw_filters_gettext_with_context', 9, 4);
  238. add_filter('ngettext', 'icl_sw_filters_ngettext', 9, 5);
  239. add_filter('ngettext_with_context', 'icl_sw_filters_nxgettext', 9, 6);
  240. }
  241. $widget_groups = $wpdb->get_results("SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name LIKE 'widget\\_%'");
  242. foreach($widget_groups as $w){
  243. add_action('update_option_' . $w->option_name, 'icl_st_update_widget_title_actions', 5, 2);
  244. }
  245. add_action('update_option_widget_text', 'icl_st_update_text_widgets_actions', 5, 2);
  246. add_action('update_option_sidebars_widgets', '__icl_st_init_register_widget_titles');
  247. if($icl_st_err_str){
  248. add_action('admin_notices', 'icl_st_admin_notices');
  249. }
  250. add_filter('get_the_author_first_name', 'icl_st_author_first_name_filter', 10, 2);
  251. add_filter('get_the_author_last_name', 'icl_st_author_last_name_filter', 10, 2);
  252. add_filter('get_the_author_nickname', 'icl_st_author_nickname_filter', 10, 2);
  253. add_filter('get_the_author_description', 'icl_st_author_description_filter', 10, 2);
  254. add_filter('the_author', 'icl_st_author_displayname_filter', 10);
  255. }
  256. add_action('profile_update', 'icl_st_register_user_strings');
  257. add_action('user_register', 'icl_st_register_user_strings');
  258. function __icl_st_init_register_widget_titles(){
  259. global $wpdb;
  260. // create a list of active widgets
  261. $active_widgets = array();
  262. $widgets = (array)get_option('sidebars_widgets');
  263. foreach($widgets as $k=>$w){
  264. if('wp_inactive_widgets' != $k && $k != 'array_version'){
  265. if(is_array($widgets[$k]))
  266. foreach($widgets[$k] as $v){
  267. $active_widgets[] = $v;
  268. }
  269. }
  270. }
  271. foreach($active_widgets as $aw){
  272. $int = preg_match('#-([0-9]+)$#i',$aw, $matches);
  273. if($int){
  274. $suffix = $matches[1];
  275. }else{
  276. $suffix = 1;
  277. }
  278. $name = preg_replace('#-[0-9]+#','',$aw);
  279. //if($name == 'rss-links') $name = 'rss';
  280. //$w = $wpdb->get_row("SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name = 'widget_{$name}'");
  281. //$value = unserialize($w->option_value);
  282. $value = get_option("widget_".$name);
  283. if(isset($value[$suffix]['title']) && $value[$suffix]['title']){
  284. $w_title = $value[$suffix]['title'];
  285. }else{
  286. $w_title = __icl_get_default_widget_title($aw);
  287. $value[$suffix]['title'] = $w_title;
  288. update_option("widget_".$name, $value);
  289. }
  290. if($w_title){
  291. icl_register_string('Widgets', 'widget title - ' . md5(apply_filters('widget_title',$w_title)), apply_filters('widget_title',$w_title));
  292. }
  293. }
  294. }
  295. function __icl_get_default_widget_title($id){
  296. if(preg_match('#archives(-[0-9]+)?$#i',$id)){
  297. $w_title = 'Archives';
  298. }elseif(preg_match('#categories(-[0-9]+)?$#i',$id)){
  299. $w_title = 'Categories';
  300. }elseif(preg_match('#calendar(-[0-9]+)?$#i',$id)){
  301. $w_title = 'Calendar';
  302. }elseif(preg_match('#links(-[0-9]+)?$#i',$id)){
  303. $w_title = 'Links';
  304. }elseif(preg_match('#meta(-[0-9]+)?$#i',$id)){
  305. $w_title = 'Meta';
  306. }elseif(preg_match('#pages(-[0-9]+)?$#i',$id)){
  307. $w_title = 'Pages';
  308. }elseif(preg_match('#recent-posts(-[0-9]+)?$#i',$id)){
  309. $w_title = 'Recent Posts';
  310. }elseif(preg_match('#recent-comments(-[0-9]+)?$#i',$id)){
  311. $w_title = 'Recent Comments';
  312. }elseif(preg_match('#rss-links(-[0-9]+)?$#i',$id)){
  313. $w_title = 'RSS';
  314. }elseif(preg_match('#search(-[0-9]+)?$#i',$id)){
  315. $w_title = 'Search';
  316. }elseif(preg_match('#tag-cloud(-[0-9]+)?$#i',$id)){
  317. $w_title = 'Tag Cloud';
  318. }else{
  319. $w_title = false;
  320. }
  321. return $w_title;
  322. }
  323. function icl_register_string($context, $name, $value, $allow_empty_value = false){
  324. global $wpdb, $sitepress, $sitepress_settings, $ICL_Pro_Translation;
  325. // if the default language is not set up return without doing anything
  326. if(
  327. !isset($sitepress_settings['existing_content_language_verified']) ||
  328. !$sitepress_settings['existing_content_language_verified']
  329. ){
  330. return;
  331. }
  332. // Check if cached (so exists)
  333. $cached = icl_t_cache_lookup($context, $name);
  334. if ($cached && isset($cached['original']) && $cached['original'] == $value) {
  335. return;
  336. }
  337. $language = $sitepress->get_default_language();
  338. $res = $wpdb->get_row("SELECT id, value, status, language FROM {$wpdb->prefix}icl_strings WHERE context='".$wpdb->escape($context)."' AND name='".$wpdb->escape($name)."'");
  339. if($res){
  340. $string_id = $res->id;
  341. $update_string = array();
  342. if($value != $res->value){
  343. $update_string['value'] = $value;
  344. }
  345. if($language != $res->language){
  346. $update_string['language'] = $language;
  347. }
  348. if(!empty($update_string)){
  349. $wpdb->update($wpdb->prefix.'icl_strings', $update_string, array('id'=>$string_id));
  350. $wpdb->update($wpdb->prefix.'icl_string_translations', array('status'=>ICL_STRING_TRANSLATION_NEEDS_UPDATE), array('string_id'=>$string_id));
  351. icl_update_string_status($string_id);
  352. }
  353. }else{
  354. if(!empty($value) && is_scalar($value) && trim($value) || $allow_empty_value){
  355. $string = array(
  356. 'language' => $language,
  357. 'context' => $context,
  358. 'name' => $name,
  359. 'value' => $value,
  360. 'status' => ICL_STRING_TRANSLATION_NOT_TRANSLATED,
  361. );
  362. $wpdb->insert($wpdb->prefix.'icl_strings', $string);
  363. $string_id = $wpdb->insert_id;
  364. }else{
  365. $string_id = 0;
  366. }
  367. }
  368. global $WPML_Sticky_Links;
  369. if(!empty($WPML_Sticky_Links) && $WPML_Sticky_Links->settings['sticky_links_strings']){
  370. require_once ICL_PLUGIN_PATH . '/inc/translation-management/pro-translation.class.php';
  371. ICL_Pro_Translation::_content_make_links_sticky($string_id, 'string', false);
  372. }
  373. return $string_id;
  374. }
  375. function icl_translate($context, $name, $original_value = false, $allow_empty_value = false, &$has_translation = null) {
  376. static $cache = null;
  377. if (isset($cache[$context][$name])) {
  378. return $cache[$context][$name];
  379. }
  380. icl_register_string($context, $name, $original_value, $allow_empty_value);
  381. $cache[$context][$name] = icl_t($context, $name, $original_value, $has_translation);
  382. return $cache[$context][$name];
  383. }
  384. function icl_st_is_registered_string($context, $name){
  385. global $wpdb;
  386. static $cache = array();
  387. if(isset($cache[$context][$name])){
  388. $string_id = $cache[$context][$name];
  389. }else{
  390. $string_id = $wpdb->get_var("
  391. SELECT id
  392. FROM {$wpdb->prefix}icl_strings WHERE context='".$wpdb->escape($context)."' AND name='".$wpdb->escape($name)."'");
  393. $cache[$context][$name] = $string_id;
  394. }
  395. return $string_id;
  396. }
  397. function icl_st_string_has_translations($context, $name){
  398. global $wpdb;
  399. $sql = "
  400. SELECT COUNT(st.id)
  401. FROM {$wpdb->prefix}icl_string_translations st
  402. JOIN {$wpdb->prefix}icl_strings s ON s.id=st.string_id
  403. WHERE s.name='".$wpdb->escape($name)."' AND s.context='".$wpdb->escape($context)."'
  404. ";
  405. return $wpdb->get_var($sql);
  406. }
  407. function icl_rename_string($context, $old_name, $new_name){
  408. global $wpdb;
  409. $wpdb->update($wpdb->prefix.'icl_strings', array('name'=>$new_name), array('context'=>$context, 'name'=>$old_name));
  410. }
  411. function icl_update_string_status($string_id){
  412. global $wpdb, $sitepress, $sitepress_settings;
  413. $st = $wpdb->get_results($wpdb->prepare("SELECT language, status FROM {$wpdb->prefix}icl_string_translations WHERE string_id=%d", $string_id));
  414. if($st){
  415. foreach($st as $t){
  416. if($sitepress_settings['st']['strings_language'] != $t->language){
  417. $translations[$t->language] = $t->status;
  418. }
  419. }
  420. $active_languages = $sitepress->get_active_languages();
  421. if(empty($translations) || max($translations) == ICL_STRING_TRANSLATION_NOT_TRANSLATED){
  422. $status = ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  423. }elseif( in_array(ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR,$translations) ){
  424. $status = ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR;
  425. }elseif(count($translations) < count($active_languages) - intval(in_array($sitepress_settings['st']['strings_language'], array_keys($active_languages)))){
  426. if(in_array(ICL_STRING_TRANSLATION_NEEDS_UPDATE,$translations)){
  427. $status = ICL_STRING_TRANSLATION_NEEDS_UPDATE;
  428. }elseif(in_array(ICL_STRING_TRANSLATION_COMPLETE,$translations)){
  429. $status = ICL_STRING_TRANSLATION_PARTIAL;
  430. }else{
  431. $status = ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  432. }
  433. }elseif(ICL_STRING_TRANSLATION_NEEDS_UPDATE == array_unique($translations)){
  434. $status = ICL_STRING_TRANSLATION_NEEDS_UPDATE;
  435. }else{
  436. if(in_array(ICL_STRING_TRANSLATION_NEEDS_UPDATE,$translations)){
  437. $status = ICL_STRING_TRANSLATION_NEEDS_UPDATE;
  438. }elseif(in_array(ICL_STRING_TRANSLATION_NOT_TRANSLATED,$translations)){
  439. $status = ICL_STRING_TRANSLATION_PARTIAL;
  440. }else{
  441. $status = ICL_STRING_TRANSLATION_COMPLETE;
  442. }
  443. }
  444. }else{
  445. $status = ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  446. }
  447. $wpdb->update($wpdb->prefix.'icl_strings', array('status'=>$status), array('id'=>$string_id));
  448. return $status;
  449. }
  450. function icl_update_string_status_all(){
  451. global $wpdb;
  452. $res = $wpdb->get_col("SELECT id FROM {$wpdb->prefix}icl_strings");
  453. foreach($res as $id){
  454. icl_update_string_status($id);
  455. }
  456. }
  457. function icl_unregister_string($context, $name){
  458. global $wpdb;
  459. $string_id = $wpdb->get_var("SELECT id FROM {$wpdb->prefix}icl_strings WHERE context='".$wpdb->escape($context)."' AND name='".$wpdb->escape($name)."'");
  460. if($string_id){
  461. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_strings WHERE id=" . $string_id);
  462. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_string_translations WHERE string_id=" . $string_id);
  463. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_string_positions WHERE string_id=" . $string_id);
  464. }
  465. do_action('icl_st_unregister_string', $string_id);
  466. }
  467. function __icl_unregister_string_multi($arr){
  468. global $wpdb;
  469. $str = join(',', array_map('intval', $arr));
  470. $wpdb->query("
  471. DELETE s.*, t.* FROM {$wpdb->prefix}icl_strings s LEFT JOIN {$wpdb->prefix}icl_string_translations t ON s.id = t.string_id
  472. WHERE s.id IN ({$str})");
  473. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_string_positions WHERE string_id IN ({$str})");
  474. do_action('icl_st_unregister_string_multi', $arr);
  475. }
  476. function icl_t($context, $name, $original_value=false, &$has_translation=null, $dont_auto_register = false){
  477. global $wpdb, $sitepress, $sitepress_settings;
  478. // if the default language is not set up return
  479. if(!isset($sitepress_settings['existing_content_language_verified'])){
  480. if(isset($has_translation)) $has_translation = false;
  481. return $original_value !== false ? $original_value : $name;
  482. }
  483. if(defined('DOING_AJAX')){
  484. $current_language = $sitepress->get_language_cookie();
  485. }elseif(is_admin()){
  486. $current_language = $sitepress->get_admin_language();
  487. }else{
  488. $current_language = $sitepress->get_current_language();
  489. }
  490. $default_language = !empty($sitepress_settings['st']['strings_language']) ? $sitepress_settings['st']['strings_language'] : $sitepress->get_default_language();
  491. if($current_language == $default_language && $original_value){
  492. $ret_val = $original_value;
  493. if(isset($has_translation)) $has_translation = false;
  494. }else{
  495. $result = icl_t_cache_lookup($context, $name);
  496. $is_string_change =
  497. $result !== false && (
  498. $result['translated'] && $result['original'] != $original_value ||
  499. !$result['translated'] && $result['value'] != $original_value
  500. );
  501. if (($result === false || $is_string_change) && !is_admin() && !$dont_auto_register && $context != 'Widgets') {
  502. // See if we should auto register the strings.
  503. if (isset($sitepress_settings['st']['icl_st_auto_reg'])) {
  504. $auto_reg = $sitepress_settings['st']['icl_st_auto_reg'];
  505. } else {
  506. $auto_reg = 'disabled';
  507. }
  508. switch ($auto_reg) {
  509. case 'auto-admin':
  510. if (current_user_can('manage_options')) {
  511. icl_register_string($context, $name, $original_value);
  512. }
  513. break;
  514. case 'auto-always':
  515. icl_register_string($context, $name, $original_value);
  516. break;
  517. }
  518. }
  519. if($result === false || is_array($result) && !$result['translated'] && $original_value){
  520. $ret_val = $original_value;
  521. if(isset($has_translation)) $has_translation = false;
  522. }else{
  523. $ret_val = $result['value'];
  524. if(isset($has_translation)) $has_translation = true;
  525. }
  526. }
  527. return $ret_val;
  528. }
  529. function icl_add_string_translation($string_id, $language, $value = null, $status = false, $translator_id = null){
  530. global $wpdb;
  531. $res = $wpdb->get_row("SELECT id, value, status FROM {$wpdb->prefix}icl_string_translations WHERE string_id='".$wpdb->escape($string_id)."' AND language='".$wpdb->escape($language)."'");
  532. // the same string should not be sent two times to translation
  533. if(isset($res->status) && $res->status == ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR && is_null($value)){
  534. return false;
  535. }
  536. if($res){
  537. $st_id = $res->id;
  538. $st_update = array();
  539. if(!is_null($value) && $value != $res->value){ // null $value is for sending to translation. don't override existing.
  540. $st_update['value'] = $value;
  541. }
  542. if($status){
  543. $st_update['status'] = $status;
  544. }elseif($status === ICL_STRING_TRANSLATION_NOT_TRANSLATED){
  545. $st_update['status'] = ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  546. }
  547. if(!empty($st_update)){
  548. if(!is_null($translator_id)){
  549. $st_update['translator_id'] = get_current_user_id();
  550. }
  551. $st_update['translation_date'] = current_time("mysql");
  552. $wpdb->update($wpdb->prefix.'icl_string_translations', $st_update, array('id'=>$st_id));
  553. }
  554. }else{
  555. if(!$status){
  556. $status = ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  557. }
  558. $st = array(
  559. 'string_id' => $string_id,
  560. 'language' => $language,
  561. 'status' => $status
  562. );
  563. if(!is_null($value)){
  564. $st['value'] = $value;
  565. }
  566. if(!is_null($translator_id)){
  567. $st_update['translator_id'] = get_current_user_id();
  568. }
  569. $wpdb->insert($wpdb->prefix.'icl_string_translations', $st);
  570. $st_id = $wpdb->insert_id;
  571. }
  572. $GLOBALS['ICL_Pro_Translation']->_content_fix_links_to_translated_content($st_id, $language, 'string');
  573. icl_update_string_status($string_id);
  574. do_action('icl_st_add_string_translation', $st_id);
  575. return $st_id;
  576. }
  577. function icl_get_string_id($string, $context){
  578. global $wpdb;
  579. $id = (int) $wpdb->get_var($wpdb->prepare("SELECT id FROM {$wpdb->prefix}icl_strings WHERE value=%s AND context=%s", $string, $context));
  580. return $id;
  581. }
  582. function icl_get_string_translations($offset=0){
  583. global $wpdb, $sitepress, $sitepress_settings, $wp_query, $icl_st_string_translation_statuses;
  584. $string_translations = array();
  585. $extra_cond = "";
  586. if(icl_st_is_translator() && isset($_GET['status']) && preg_match("#".ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR."-(.+)#", $_GET['status'], $matches)){
  587. $status_filter = ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR;
  588. $status_filter_lang = $matches[1];
  589. $lcode_alias = str_replace('-', '', $status_filter_lang);
  590. $extra_cond .= " AND str_{$lcode_alias}.language = '{$status_filter_lang}' ";
  591. }else{
  592. $status_filter = isset($_GET['status']) ? intval($_GET['status']) : false;
  593. }
  594. $search_filter = isset($_GET['search']) ? $_GET['search'] : false;
  595. $exact_match = isset($_GET['em']) ? $_GET['em'] == 1 : false;
  596. if($status_filter !== false){
  597. if($status_filter == ICL_STRING_TRANSLATION_COMPLETE){
  598. $extra_cond .= " AND s.status = " . ICL_STRING_TRANSLATION_COMPLETE;
  599. }elseif($status_filter == ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR){
  600. ; // do nothing
  601. }else{
  602. $extra_cond .= " AND status IN (" . ICL_STRING_TRANSLATION_PARTIAL . "," . ICL_STRING_TRANSLATION_NEEDS_UPDATE . "," . ICL_STRING_TRANSLATION_NOT_TRANSLATED . "," . ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR . ")";
  603. }
  604. }
  605. if($search_filter != false){
  606. if($exact_match){
  607. $extra_cond .= " AND s.value = '". $wpdb->escape($search_filter)."' ";
  608. }else{
  609. $extra_cond .= " AND s.value LIKE '%". $wpdb->escape($search_filter)."%' ";
  610. }
  611. }
  612. $context_filter = isset($_GET['context']) ? $_GET['context'] : false;
  613. if($context_filter !== false){
  614. $extra_cond .= " AND s.context = '" . $wpdb->escape($context_filter) . "'";
  615. }
  616. if(isset($_GET['show_results']) && $_GET['show_results']=='all'){
  617. $limit = 9999;
  618. $offset = 0;
  619. }else{
  620. $limit = $sitepress_settings['st']['strings_per_page'];
  621. if(!isset($_GET['paged'])) $_GET['paged'] = 1;
  622. $offset = ($_GET['paged']-1)*$limit;
  623. }
  624. /* TRANSLATOR - START */
  625. if(icl_st_is_translator()){
  626. $user_lang_pairs = get_user_meta(get_current_user_id(), $wpdb->prefix.'language_pairs', true);
  627. if(!empty($status_filter_lang)){
  628. $_joins = $_sels = $_where = array();
  629. foreach($sitepress->get_active_languages() as $l){
  630. if($l['code'] == $sitepress_settings['st']['strings_language']) continue;
  631. $lcode_alias = str_replace('-', '', $l['code']);
  632. $_sels[] = "str_{$lcode_alias}.id AS id_{$lcode_alias},
  633. str_{$lcode_alias}.status AS status_{$lcode_alias},
  634. str_{$lcode_alias}.value AS value_{$lcode_alias},
  635. str_{$lcode_alias}.translator_id AS translator_{$lcode_alias},
  636. str_{$lcode_alias}.translation_date AS date_{$lcode_alias}
  637. ";
  638. $_joins[] = " LEFT JOIN {$wpdb->prefix}icl_string_translations str_{$lcode_alias} ON str_{$lcode_alias}.string_id = s.id AND str_{$lcode_alias}.language = '{$l['code']}'";
  639. }
  640. $sql = "
  641. SELECT SQL_CALC_FOUND_ROWS s.id AS string_id, s.language AS string_language, s.context, s.name, s.value, s.status,
  642. " . join(", ", $_sels) . "
  643. FROM {$wpdb->prefix}icl_strings s
  644. " . join("\n", $_joins) . "
  645. WHERE
  646. str_{$status_filter_lang}.status = ".ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR." AND
  647. (str_{$status_filter_lang}.translator_id IS NULL OR str_{$status_filter_lang}.translator_id = ".get_current_user_id().")
  648. {$extra_cond}
  649. ORDER BY string_id DESC
  650. LIMIT {$offset},{$limit}
  651. ";
  652. //echo '<pre>' . print_r($sql,1) . '</pre>';
  653. $res = $wpdb->get_results($sql, ARRAY_A);
  654. }else{
  655. $_joins = $_sels = $_where = array();
  656. foreach($sitepress->get_active_languages() as $l){
  657. if($l['code'] == $sitepress_settings['st']['strings_language']
  658. || empty($user_lang_pairs[$sitepress_settings['st']['strings_language']][$l['code']])) continue;
  659. $lcode_alias = str_replace('-', '', $l['code']);
  660. $lcode_alias = str_replace('-', '', $l['code']);
  661. $_sels[] = "str_{$lcode_alias}.id AS id_{$lcode_alias},
  662. str_{$lcode_alias}.status AS status_{$lcode_alias},
  663. str_{$lcode_alias}.value AS value_{$lcode_alias},
  664. str_{$lcode_alias}.translator_id AS translator_{$lcode_alias},
  665. str_{$lcode_alias}.translation_date AS date_{$lcode_alias}
  666. ";
  667. $_joins[] = "LEFT JOIN {$wpdb->prefix}icl_string_translations str_{$lcode_alias} ON str_{$lcode_alias}.string_id = s.id AND str_{$lcode_alias}.language='{$l['code']}'";
  668. if($status_filter == ICL_STRING_TRANSLATION_COMPLETE){
  669. $_where[] .= " AND str_{$lcode_alias}.status = " . ICL_STRING_TRANSLATION_COMPLETE;
  670. }else{
  671. if(empty($_lwhere)){
  672. $_lwhere = ' AND (';
  673. foreach($sitepress->get_active_languages() as $l2){
  674. if($l2['code'] == $sitepress_settings['st']['strings_language'] || empty($user_lang_pairs[$sitepress_settings['st']['strings_language']][$l2['code']])) continue;
  675. $l2code_alias = str_replace('-', '', $l2['code']);
  676. $_lwheres[] = " str_{$l2code_alias}.status = " . ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR . " OR
  677. str_{$l2code_alias}.translator_id = " . get_current_user_id() ;
  678. }
  679. $_lwhere .= join(' OR ', $_lwheres ) . ')';
  680. $_where[] = $_lwhere;
  681. }
  682. }
  683. }
  684. $sql = "
  685. SELECT SQL_CALC_FOUND_ROWS s.id AS string_id, s.language AS string_language, s.context, s.name, s.value, s.status, ".
  686. join(', ', $_sels) . "
  687. FROM {$wpdb->prefix}icl_strings s " . join("\n", $_joins) . "
  688. WHERE s.language = '{$sitepress_settings['st']['strings_language']}' ".join(' ', $_where) . "
  689. {$extra_cond}
  690. ORDER BY s.id DESC
  691. LIMIT {$offset},{$limit}
  692. ";
  693. $res = $wpdb->get_results($sql, ARRAY_A);
  694. }
  695. $wp_query->found_posts = $wpdb->get_var("SELECT FOUND_ROWS()");
  696. $wp_query->query_vars['posts_per_page'] = $limit;
  697. $wp_query->max_num_pages = ceil($wp_query->found_posts/$limit);
  698. if($res){
  699. if(!empty($status_filter_lang)){
  700. foreach($res as $row){
  701. $_translations = array();
  702. foreach($sitepress->get_active_languages() as $l){
  703. if($l['code'] == $sitepress_settings['st']['strings_language']) continue;
  704. $lcode_alias = str_replace('-', '', $l['code']);
  705. if($row['id_'. $lcode_alias]){
  706. $_translations[$l['code']] = array(
  707. 'id' => $row['id_'. $lcode_alias],
  708. 'status' => $row['status_'. $lcode_alias],
  709. 'language' => $l['code'],
  710. 'value' => $row['value_'. $lcode_alias],
  711. 'translator_id' => $row['translator_'. $lcode_alias],
  712. 'translation_date' => $row['date_'. $lcode_alias]
  713. );
  714. }
  715. }
  716. $string_translations[$row['string_id']] = array(
  717. 'string_id' => $row['string_id'],
  718. 'string_language' => $row['string_language'],
  719. 'context' => $row['context'],
  720. 'name' => $row['name'],
  721. 'value' => $row['value'],
  722. 'status' => ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR,
  723. 'translations' => $_translations
  724. );
  725. }
  726. //echo '<pre>' . print_r($string_translations,1) . '</pre>';
  727. }else{
  728. foreach($res as $row){
  729. $_translations = array();
  730. $_status = ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  731. $_statuses = array();
  732. foreach($sitepress->get_active_languages() as $l){
  733. if($l['code'] == $sitepress_settings['st']['strings_language'] || empty($user_lang_pairs[$sitepress_settings['st']['strings_language']][$l['code']])) continue;
  734. $lcode_alias = str_replace('-', '', $l['code']);
  735. if($row['id_'. $lcode_alias]){
  736. $_translations[$l['code']] = array(
  737. 'id' => $row['id_'. $lcode_alias],
  738. 'status' => $row['status_'. $lcode_alias],
  739. 'language' => $l['code'],
  740. 'value' => $row['value_'. $lcode_alias],
  741. 'translator_id' => $row['translator_'. $lcode_alias],
  742. 'translation_date' => $row['date_'. $lcode_alias]
  743. );
  744. }
  745. $_statuses[$l['code']] = @intval($row['status_'. $lcode_alias]);
  746. if($row['status_'. $lcode_alias] == ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR){
  747. $_status == ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR;
  748. }
  749. }
  750. $_statuses = array_values($_statuses);
  751. $_statuses = array_unique($_statuses);
  752. if($_statuses == array(ICL_STRING_TRANSLATION_NOT_TRANSLATED)){
  753. $_status = ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  754. }elseif($_statuses == array(ICL_STRING_TRANSLATION_COMPLETE, ICL_STRING_TRANSLATION_NOT_TRANSLATED)){
  755. $_status = ICL_STRING_TRANSLATION_PARTIAL;
  756. }elseif($_statuses == array(ICL_STRING_TRANSLATION_COMPLETE)){
  757. $_status = ICL_STRING_TRANSLATION_COMPLETE;
  758. }elseif(in_array(ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR, $_statuses) || in_array(ICL_STRING_TRANSLATION_NEEDS_UPDATE, $_statuses)){
  759. $_status = ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR;
  760. }
  761. $string_translations[$row['string_id']] = array(
  762. 'string_id' => $row['string_id'],
  763. 'string_language' => $row['string_language'],
  764. 'context' => $row['context'],
  765. 'name' => $row['name'],
  766. 'value' => $row['value'],
  767. 'status' => $_status,
  768. 'translations' => $_translations
  769. );
  770. }
  771. }
  772. }
  773. /* TRANSLATOR - END */
  774. }else{
  775. // removed check for language = default lang
  776. if($status_filter != ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR){
  777. $res = $wpdb->get_results("
  778. SELECT SQL_CALC_FOUND_ROWS id AS string_id, language AS string_language, context, name, value, status
  779. FROM {$wpdb->prefix}icl_strings s
  780. WHERE
  781. 1
  782. {$extra_cond}
  783. ORDER BY string_id DESC
  784. LIMIT {$offset},{$limit}
  785. ", ARRAY_A);
  786. }else{
  787. $res = $wpdb->get_results("
  788. SELECT SQL_CALC_FOUND_ROWS s.id AS string_id, s.language AS string_language, s.context, s.name, s.value, " . ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR . " AS status
  789. FROM {$wpdb->prefix}icl_strings s
  790. JOIN {$wpdb->prefix}icl_string_translations str ON str.string_id = s.id
  791. WHERE
  792. str.status = " . ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR . "
  793. {$extra_cond}
  794. ORDER BY string_id DESC
  795. LIMIT {$offset},{$limit}
  796. ", ARRAY_A);
  797. }
  798. $wp_query->found_posts = $wpdb->get_var("SELECT FOUND_ROWS()");
  799. $wp_query->query_vars['posts_per_page'] = $limit;
  800. $wp_query->max_num_pages = ceil($wp_query->found_posts/$limit);
  801. if($res){
  802. $extra_cond = '';
  803. if(isset($_GET['translation_language'])){
  804. $extra_cond .= " AND language='".$wpdb->escape($_GET['translation_language'])."'";
  805. }
  806. foreach($res as $row){
  807. $string_translations[$row['string_id']] = $row;
  808. $tr = $wpdb->get_results("
  809. SELECT id, language, status, value, translator_id, translation_date
  810. FROM {$wpdb->prefix}icl_string_translations
  811. WHERE string_id={$row['string_id']} {$extra_cond}
  812. ", ARRAY_A);
  813. if($tr){
  814. foreach($tr as $t){
  815. $string_translations[$row['string_id']]['translations'][$t['language']] = $t;
  816. }
  817. }
  818. }
  819. }
  820. }
  821. return $string_translations;
  822. }
  823. function icl_get_relative_translation_status($string_id, $translator_id){
  824. global $wpdb, $sitepress, $sitepress_settings;
  825. $user_lang_pairs = get_user_meta(get_current_user_id(), $wpdb->prefix.'language_pairs', true);
  826. $src_langs = array_intersect(array_keys($sitepress->get_active_languages()), array_keys($user_lang_pairs[$sitepress_settings['st']['strings_language']]));
  827. if(empty($src_langs)) return ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  828. $sql = "SELECT st.status
  829. FROM {$wpdb->prefix}icl_strings s
  830. JOIN {$wpdb->prefix}icl_string_translations st ON s.id = st.string_id
  831. WHERE st.language IN ('" . join("','", $src_langs) . "') AND s.id = %d
  832. ";
  833. $statuses = $wpdb->get_col($wpdb->prepare($sql, $string_id));
  834. $status = ICL_STRING_TRANSLATION_NOT_TRANSLATED;
  835. $one_incomplete = false;
  836. foreach($statuses as $s){
  837. if($s == ICL_STRING_TRANSLATION_COMPLETE){
  838. $status = ICL_STRING_TRANSLATION_COMPLETE;
  839. }elseif($s == ICL_STRING_TRANSLATION_NOT_TRANSLATED){
  840. $one_incomplete = true;
  841. }
  842. }
  843. if($status == ICL_STRING_TRANSLATION_COMPLETE && $one_incomplete){
  844. $status = ICL_STRING_TRANSLATION_PARTIAL;
  845. }
  846. return $status;
  847. }
  848. function icl_get_strigs_tracked_in_pages($string_translations){
  849. global $wpdb;
  850. // get string position in page - if found
  851. $found_strings = $strings_in_page = array();
  852. foreach(array_keys((array)$string_translations) as $string_id){
  853. $found_strings[] = $string_id;
  854. }
  855. if($found_strings){
  856. $res = $wpdb->get_results("
  857. SELECT kind, string_id FROM {$wpdb->prefix}icl_string_positions
  858. WHERE string_id IN (".implode(',', $found_strings).")");
  859. foreach($res as $row){
  860. $strings_in_page[$row->kind][$row->string_id] = true;
  861. }
  862. }
  863. return $strings_in_page;
  864. }
  865. function icl_sw_filters_blogname($val){
  866. return icl_t('WP', 'Blog Title', $val);
  867. }
  868. function icl_sw_filters_blogdescription($val){
  869. return icl_t('WP', 'Tagline', $val);
  870. }
  871. function icl_sw_filters_widget_title($val){
  872. return icl_t('Widgets', 'widget title - ' . md5($val) , $val);
  873. }
  874. function icl_sw_filters_widget_text($val){
  875. $val = icl_t('Widgets', 'widget body - ' . md5($val) , $val);
  876. return $val;
  877. }
  878. function icl_sw_filters_gettext($translation, $text, $domain, $name = false){
  879. global $sitepress_settings;
  880. $has_translation = 0;
  881. $dbt = debug_backtrace();
  882. $dbt4 = @str_replace('\\','/',$dbt[4]['file']);
  883. $wp_plugin_dir = str_replace('\\','/',WP_PLUGIN_DIR);
  884. $wpmu_plugin_dir = str_replace('\\','/',WPMU_PLUGIN_DIR);
  885. if(0 === strpos($dbt4, $wp_plugin_dir)){
  886. if(dirname($dbt4) == $wp_plugin_dir){
  887. $plugin_folder = basename(str_replace($wp_plugin_dir, '', $dbt4));
  888. }else{
  889. $exp = explode('/', ltrim(str_replace($wp_plugin_dir, '', $dbt4),'/'));
  890. $plugin_folder = $exp[0];
  891. }
  892. $context = 'plugin ' . $plugin_folder;
  893. }elseif(0 === strpos($dbt4, $wpmu_plugin_dir)){
  894. $context = ($domain != 'default') ? 'plugin ' . $domain : 'plugin';
  895. }else{
  896. $context = ($domain != 'default') ? 'theme ' . $domain : 'WordPress';
  897. }
  898. // track strings if the user has enabled this and if it's and editor or admin
  899. if(isset($sitepress_settings['st']['track_strings']) && $sitepress_settings['st']['track_strings'] && current_user_can('edit_others_posts')){
  900. icl_st_track_string($text, $context, ICL_STRING_TRANSLATION_STRING_TRACKING_TYPE_PAGE);
  901. }
  902. if(empty($name)){
  903. $name = md5($text);
  904. }
  905. $ret_translation = icl_t($context, $name, $text, $has_translation);
  906. if(false === $has_translation){
  907. $ret_translation = $translation;
  908. }
  909. if(isset($_GET['icl_string_track_value']) && isset($_GET['icl_string_track_context'])
  910. && stripslashes($_GET['icl_string_track_context']) == $context && stripslashes($_GET['icl_string_track_value']) == $text){
  911. $ret_translation = '<span style="background-color:'.$sitepress_settings['st']['hl_color'].'">' . $ret_translation . '</span>';
  912. }
  913. return $ret_translation;
  914. }
  915. function icl_sw_filters_gettext_with_context($translation, $text, $_gettext_context, $domain){
  916. return icl_sw_filters_gettext($translation, $text, $domain, $_gettext_context . ': ' . $text);
  917. }
  918. function icl_sw_filters_ngettext($translation, $single, $plural, $number, $domain, $_gettext_context = false){
  919. if($number == 1){
  920. return @sprintf(icl_sw_filters_gettext($translation, $single, $domain, $_gettext_context), $number);
  921. }else{
  922. return @sprintf(icl_sw_filters_gettext($translation, $plural, $domain, $_gettext_context), $number);
  923. }
  924. }
  925. function icl_sw_filters_nxgettext($translation, $single, $plural, $number, $_gettext_context, $domain){
  926. return icl_sw_filters_ngettext($translation, $single, $plural, $number, $domain, $_gettext_context);
  927. }
  928. function icl_st_author_first_name_filter($value, $user_id){
  929. global $sitepress_settings;
  930. if(false === $user_id){
  931. global $authordata;
  932. $user_id = $authordata->data->ID;
  933. }
  934. $user = new WP_User($user_id);
  935. if ( is_array( $user->roles ) && array_intersect($user->roles, (array)$sitepress_settings['st']['translated-users'])){
  936. $value = icl_st_translate_author_fields('first_name', $value, $user_id);
  937. }
  938. return $value;
  939. }
  940. function icl_st_author_last_name_filter($value, $user_id){
  941. global $sitepress_settings;
  942. if(false === $user_id){
  943. global $authordata;
  944. $user_id = $authordata->data->ID;
  945. }
  946. $user = new WP_User($user_id);
  947. if ( is_array( $user->roles ) && array_intersect($user->roles, (array)$sitepress_settings['st']['translated-users'])){
  948. $value = icl_st_translate_author_fields('last_name', $value, $user_id);
  949. }
  950. return $value;
  951. }
  952. function icl_st_author_nickname_filter($value, $user_id){
  953. global $sitepress_settings;
  954. if(false === $user_id){
  955. global $authordata;
  956. $user_id = $authordata->data->ID;
  957. }
  958. $user = new WP_User($user_id);
  959. if ( is_array( $user->roles ) && array_intersect($user->roles, (array)$sitepress_settings['st']['translated-users'])){
  960. $value = icl_st_translate_author_fields('nickname', $value, $user_id);
  961. }
  962. return $value;
  963. }
  964. function icl_st_author_description_filter($value, $user_id){
  965. global $sitepress_settings;
  966. if(false === $user_id){
  967. global $authordata;
  968. if(empty($authordata->data)) return $value;
  969. $user_id = $authordata->data->ID;
  970. }
  971. $user = new WP_User($user_id);
  972. if ( is_array( $user->roles ) && array_intersect($user->roles, (array)$sitepress_settings['st']['translated-users'])){
  973. $value = icl_st_translate_author_fields('description', $value, $user_id);
  974. }
  975. return $value;
  976. }
  977. function icl_st_author_displayname_filter($value){
  978. global $authordata, $sitepress_settings;
  979. if(isset($authordata->ID)){
  980. $user = new WP_User($authordata->ID);
  981. if ( is_array( $user->roles ) && array_intersect($user->roles, (array)$sitepress_settings['st']['translated-users'])){
  982. $value = icl_st_translate_author_fields('display_name', $value, isset($authordata->ID)?$authordata->ID:null);
  983. }
  984. }
  985. return $value;
  986. }
  987. function icl_st_translate_author_fields($field, $value, $user_id){
  988. global $sitepress_settings;
  989. if(empty($user_id)) $user_id = get_current_user_id();
  990. $user = new WP_User($user_id);
  991. if ( is_array( $user->roles ) && array_intersect($user->roles, (array)$sitepress_settings['st']['translated-users'])){
  992. $value = icl_translate('Authors', $field . '_' . $user_id, $value, true);
  993. }
  994. return $value;
  995. }
  996. function icl_st_register_user_strings($user_id){
  997. global $sitepress_settings;
  998. $user = new WP_User($user_id);
  999. if ( is_array( $user->roles ) && array_intersect($user->roles, (array)$sitepress_settings['st']['translated-users'])){
  1000. $fields = array('first_name', 'last_name', 'nickname', 'description');
  1001. foreach($fields as $field){
  1002. icl_register_string('Authors', $field . '_' . $user_id, get_the_author_meta($field, $user_id), true, true);
  1003. }
  1004. icl_register_string('Authors', 'display_name_' . $user_id, $user->display_name, true, true);
  1005. }
  1006. }
  1007. function icl_st_register_user_strings_all(){
  1008. global $wpdb;
  1009. $users = get_users(array('blog_id'=>$wpdb->blogid, 'fields'=>'ID'));
  1010. foreach($users as $uid){
  1011. icl_st_register_user_strings($uid);
  1012. }
  1013. }
  1014. function icl_st_update_string_actions($context, $name, $old_value, $new_value){
  1015. global $wpdb;
  1016. if($new_value != $old_value){
  1017. $string = $wpdb->get_row($wpdb->prepare("SELECT id, value, status FROM {$wpdb->prefix}icl_strings WHERE context=%s AND name=%s", $context, $name));
  1018. if(!$string){
  1019. icl_register_string($context, $name, $new_value);
  1020. return;
  1021. }
  1022. $wpdb->update($wpdb->prefix . 'icl_strings', array('value'=>$new_value), array('id'=>$string->id));
  1023. if($string->status == ICL_STRING_TRANSLATION_COMPLETE || $string->status == ICL_STRING_TRANSLATION_PARTIAL){
  1024. $wpdb->update($wpdb->prefix . 'icl_string_translations', array('status'=>ICL_STRING_TRANSLATION_NEEDS_UPDATE), array('string_id'=>$string->id));
  1025. $wpdb->update($wpdb->prefix . 'icl_strings', array('status'=>ICL_STRING_TRANSLATION_NEEDS_UPDATE), array('id'=>$string->id));
  1026. }
  1027. if($context == 'Widgets' && $new_value){
  1028. if(0 === strpos($name, 'widget title - ')){
  1029. icl_rename_string('Widgets', 'widget title - ' . md5($old_value), 'widget title - ' . md5($new_value));
  1030. }elseif(0 === strpos($name, 'widget body - ')){
  1031. icl_rename_string('Widgets', 'widget body - ' . md5($old_value), 'widget body - ' . md5($new_value));
  1032. }
  1033. }
  1034. }
  1035. }
  1036. function icl_st_update_blogname_actions($old, $new){
  1037. icl_st_update_string_actions('WP', 'Blog Title', $old, $new);
  1038. }
  1039. function icl_st_update_blogdescription_actions($old, $new){
  1040. icl_st_update_string_actions('WP', 'Tagline', $old, $new);
  1041. }
  1042. function icl_st_update_widget_title_actions($old_options, $new_options){
  1043. if(isset($new_options['title'])){ // case of 1 instance only widgets
  1044. $buf = $new_options;
  1045. unset($new_options);
  1046. $new_options[0] = $buf;
  1047. unset($buf);
  1048. $buf = $old_options;
  1049. unset($old_options);
  1050. $old_options[0] = $buf;
  1051. unset($buf);
  1052. }
  1053. foreach($new_options as $k=>$o){
  1054. if(isset($o['title'])){
  1055. if(isset($old_options[$k]['title']) && $old_options[$k]['title']){
  1056. icl_st_update_string_actions('Widgets', 'widget title - ' . md5(apply_filters('widget_title', $old_options[$k]['title'])), apply_filters('widget_title', $old_options[$k]['title']), apply_filters('widget_title', $o['title']));
  1057. }else{
  1058. if($new_options[$k]['title']){
  1059. icl_register_string('Widgets', 'widget title - ' . md5(apply_filters('widget_title', $new_options[$k]['title'])), apply_filters('widget_title', $new_options[$k]['title']));
  1060. }
  1061. }
  1062. }
  1063. }
  1064. }
  1065. function icl_st_update_text_widgets_actions($old_options, $new_options){
  1066. global $sitepress_settings, $wpdb;
  1067. // remove filter for showing permalinks instead of sticky links while saving
  1068. $GLOBALS['__disable_absolute_links_permalink_filter'] = 1;
  1069. $widget_text = get_option('widget_text');
  1070. if(is_array($widget_text)){
  1071. foreach($widget_text as $k=>$w){
  1072. if(isset($old_options[$k]['text']) && trim($old_options[$k]['text']) && $old_options[$k]['text'] != $w['text']){
  1073. $old_md5 = md5(apply_filters('widget_text', $old_options[$k]['text']));
  1074. $string = $wpdb->get_row($wpdb->prepare("SELECT id, value, status FROM {$wpdb->prefix}icl_strings WHERE context=%s AND name=%s", 'Widgets', 'widget body - ' . $old_md5));
  1075. if ($string) {
  1076. icl_st_update_string_actions('Widgets', 'widget body - ' . $old_md5, apply_filters('widget_text', $old_options[$k]['text']), apply_filters('widget_text', $w['text']));
  1077. } else {
  1078. icl_register_string('Widgets', 'widget body - ' . md5(apply_filters('widget_text', $w['text'])), apply_filters('widget_text', $w['text']));
  1079. }
  1080. }elseif(isset($new_options[$k]['text']) && $old_options[$k]['text']!=$new_options[$k]['text']){
  1081. icl_register_string('Widgets', 'widget body - ' . md5(apply_filters('widget_text', $new_options[$k]['text'])), apply_filters('widget_text', $new_options[$k]['text']));
  1082. }
  1083. }
  1084. }
  1085. // add back the filter for showing permalinks instead of sticky links after saving
  1086. unset($GLOBALS['__disable_absolute_links_permalink_filter']);
  1087. }
  1088. function icl_t_cache_lookup($context, $name){
  1089. global $sitepress_settings, $sitepress, $wpdb;
  1090. static $icl_st_cache;
  1091. $ret_value = false;
  1092. if(!isset($icl_st_cache[$context])){ //CACHE MISS (context)
  1093. $icl_st_cache[$context] = array();
  1094. // determine the correct current language
  1095. if(defined('DOING_AJAX')){
  1096. $current_language = $sitepress->get_language_cookie();
  1097. }elseif(is_admin()){
  1098. $current_language = $sitepress->get_admin_language();
  1099. }else{
  1100. $current_language = $sitepress->get_current_language();
  1101. }
  1102. $default_language = $sitepress->get_default_language();
  1103. // workaround for multi-site setups - part i
  1104. global $switched, $switched_stack;
  1105. if(isset($switched) && $switched){
  1106. $prev_blog_id = $wpdb->blogid;
  1107. $wpdb->set_blog_id($switched_stack[0]);
  1108. }
  1109. // THE QUERY
  1110. $res = $wpdb->get_results($wpdb->prepare("
  1111. SELECT s.name, s.value, t.value AS translation_value, t.status
  1112. FROM {$wpdb->prefix}icl_strings s
  1113. LEFT JOIN {$wpdb->prefix}icl_string_translations t ON s.id = t.string_id
  1114. WHERE s.context = %s
  1115. AND (t.language = %s OR t.language IS NULL)
  1116. ", $context, $current_language), ARRAY_A);
  1117. // workaround for multi-site setups - part ii
  1118. if(isset($switched) && $switched){
  1119. $wpdb->set_blog_id($prev_blog_id);
  1120. }
  1121. // SAVE QUERY RESULTS
  1122. if($res){
  1123. foreach($res as $row){
  1124. if($row['status'] != ICL_STRING_TRANSLATION_COMPLETE || empty($row['translation_value'])){
  1125. $icl_st_cache[$context][$row['name']]['translated'] = false;
  1126. $icl_st_cache[$context][$row['name']]['value'] = $row['value'];
  1127. }else{
  1128. $icl_st_cache[$context][$row['name']]['translated'] = true;
  1129. $icl_st_cache[$context][$row['name']]['value'] = $row['translation_value'];
  1130. $icl_st_cache[$context][$row['name']]['original'] = $row['value'];
  1131. }
  1132. }
  1133. }
  1134. }
  1135. if(isset($icl_st_cache[$context][$name])){
  1136. $ret_value = $icl_st_cache[$context][$name];
  1137. }
  1138. return $ret_value;
  1139. }
  1140. function icl_st_get_contexts($status){
  1141. global $wpdb, $sitepress, $sitepress_settings;
  1142. $extra_cond = '';
  1143. if($status !== false){
  1144. if($status == ICL_STRING_TRANSLATION_COMPLETE){
  1145. $extra_cond .= " AND s.status = " . ICL_STRING_TRANSLATION_COMPLETE;
  1146. }else{
  1147. $extra_cond .= " AND s.status IN (" . ICL_STRING_TRANSLATION_PARTIAL . "," . ICL_STRING_TRANSLATION_NEEDS_UPDATE . "," . ICL_STRING_TRANSLATION_NOT_TRANSLATED . ")";
  1148. }
  1149. }
  1150. if(icl_st_is_translator()){
  1151. $user_langs = get_user_meta(get_current_user_id(), $wpdb->prefix.'language_pairs', true);
  1152. $active_langs = $sitepress->get_active_languages();
  1153. if(!empty($user_langs[$sitepress_settings['st']['strings_language']])){
  1154. foreach($user_langs[$sitepress_settings['st']['strings_language']] as $lang=>$one){
  1155. if(isset($active_langs[$lang])){
  1156. $lcode_alias = str_replace('-', '', $lang);
  1157. $joins[] = " JOIN {$wpdb->prefix}icl_string_translations {$lcode_alias}_str ON {$lcode_alias}_str.string_id = s.id AND {$lcode_alias}_str.language='{$lcode_alias}' AND
  1158. (
  1159. {$lcode_alias}_str.status = " . ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR .
  1160. " OR {$lcode_alias}_str.translator_id = " . get_current_user_id()
  1161. . ")" . "\n";
  1162. }
  1163. }
  1164. $sql = "
  1165. SELECT s.context, COUNT(s.context) AS c FROM {$wpdb->prefix}icl_strings s
  1166. ".join("\n", $joins)."
  1167. WHERE 1 {$extra_cond}
  1168. GROUP BY context
  1169. ORDER BY context ASC
  1170. ";
  1171. $results = $wpdb->get_results($sql);
  1172. }
  1173. }else{
  1174. $results = $wpdb->get_results("
  1175. SELECT context, COUNT(context) AS c
  1176. FROM {$wpdb->prefix}icl_strings s
  1177. WHERE language='{$sitepress->get_current_language()}' {$extra_cond}
  1178. GROUP BY context
  1179. ORDER BY context ASC");
  1180. }
  1181. return $results;
  1182. }
  1183. function icl_st_admin_notices(){
  1184. global $icl_st_err_str;
  1185. if($icl_st_err_str){
  1186. echo '<div class="error"><p>' . $icl_st_err_str . '</p></div>';
  1187. }
  1188. }
  1189. function icl_st_scan_theme_files($dir = false, $recursion = 0){
  1190. require_once ICL_PLUGIN_PATH . '/inc/potx.php';
  1191. static $scan_stats = false;
  1192. static $recursion, $scanned_files = array();
  1193. global $icl_scan_theme_found_domains, $sitepress, $sitepress_settings;
  1194. if($dir === false){
  1195. $dir = TEMPLATEPATH;
  1196. }
  1197. if(!$scan_stats){
  1198. $scan_stats = sprintf(__('Scanning theme folder: %s', 'wpml-string-translation'),$dir) . PHP_EOL;
  1199. }
  1200. $dh = opendir($dir);
  1201. while(false !== ($file = readdir($dh))){
  1202. if($file=="." || $file=="..") continue;
  1203. if(is_dir($dir . "/" . $file)){
  1204. $recursion++;
  1205. $scan_stats .= str_repeat("\t",$recursion) . sprintf(__('Opening folder: %s', 'wpml-string-translation'), $dir . "/" . $file) . PHP_EOL;
  1206. icl_st_scan_theme_files($dir . "/" . $file, $recursion);
  1207. $recursion--;
  1208. }elseif(preg_match('#(\.php|\.inc)$#i', $file)){
  1209. // THE potx way
  1210. $scan_stats .= str_repeat("\t",$recursion) . sprintf(__('Scanning file: %s', 'wpml-string-translation'), $dir . "/" . $file) . PHP_EOL;
  1211. $scanned_files[] = $dir . "/" . $file;
  1212. _potx_process_file($dir . "/" . $file, 0, '__icl_st_scan_theme_files_store_results','_potx_save_version', POTX_API_7);
  1213. }else{
  1214. $scan_stats .= str_repeat("\t",$recursion) . sprintf(__('Skipping file: %s', 'wpml-string-translation'), $dir . "/" . $file) . PHP_EOL;
  1215. }
  1216. }
  1217. if($dir == TEMPLATEPATH && TEMPLATEPATH != STYLESHEETPATH){
  1218. static $double_scan = true;
  1219. icl_st_scan_theme_files(STYLESHEETPATH);
  1220. $double_scan = false;
  1221. }
  1222. if(!$recursion && (empty($double_scan) || !$double_scan)){
  1223. global $__icl_registered_strings;
  1224. $scan_stats .= __('Done scanning files', 'wpml-string-translation') . PHP_EOL;
  1225. $sitepress_settings['st']['theme_localization_domains'] = array_keys($icl_scan_theme_found_domains);
  1226. $sitepress->save_settings($sitepress_settings);
  1227. closedir($dh);
  1228. $scan_stats_all = __('= Your theme was scanned for texts =', 'wpml-string-translation') . '<br />' .
  1229. __('The following files were processed:', 'wpml-string-translation') . '<br />' .
  1230. '<ol style="font-size:10px;"><li>' . join('</li><li>', $scanned_files) . '</li></ol>' .
  1231. sprintf(__('WPML found %s strings. They were added to the string translation table.','wpml-string-translation'),count($__icl_registered_strings)) .
  1232. '<br /><a href="#" onclick="jQuery(this).next().toggle();return false;">' . __('More details', 'wpml-string-translation') . '</a>'.
  1233. '<textarea style="display:none;width:100%;height:150px;font-size:10px;">' . $scan_stats . '</textarea>';
  1234. return $scan_stats_all;
  1235. }
  1236. }
  1237. function __icl_st_scan_theme_files_store_results($string, $domain, $_gettext_context, $file, $line){
  1238. global $icl_scan_theme_found_domains;
  1239. $string = str_replace(array('\"',"\\'"), array('"',"'"), $string);
  1240. //replace extra backslashes added by _potx_process_file
  1241. $string = str_replace(array('\\\\'), array('\\'), $string);
  1242. if(!isset($icl_scan_theme_found_domains[$domain])){
  1243. $icl_scan_theme_found_domains[$domain] = true;
  1244. }
  1245. global $wpdb, $__icl_registered_strings;
  1246. $context = false;
  1247. if(!isset($__icl_registered_strings)){
  1248. $__icl_registered_strings = array();
  1249. // clear existing entries (both source and page type)
  1250. $context = $domain ? 'theme ' . $domain : 'theme';
  1251. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_string_positions WHERE string_id IN
  1252. (SELECT id FROM {$wpdb->prefix}icl_strings WHERE context = '{$context}')");
  1253. }
  1254. if(!isset($__icl_registered_strings[$domain.'||'.$string.'||'.$_gettext_context])){
  1255. if(!$domain){
  1256. $context = 'theme';
  1257. }else{
  1258. $context = 'theme ' . $domain;
  1259. }
  1260. $name = $_gettext_context ? $_gettext_context : md5($string);
  1261. icl_register_string($context, $name, $string);
  1262. $__icl_registered_strings[$domain.'||'.$string.'||'.$_gettext_context] = true;
  1263. }
  1264. // store position in source
  1265. icl_st_track_string($string, $context, ICL_STRING_TRANSLATION_STRING_TRACKING_TYPE_SOURCE, $file, $line);
  1266. }
  1267. function icl_st_scan_plugin_files($plugin, $recursion = 0){
  1268. require_once ICL_PLUGIN_PATH . '/inc/potx.php';
  1269. static $recursion, $scanned_files = array();
  1270. static $scan_stats = false;
  1271. global $icl_scan_plugin_found_domains, $icl_st_p_scan_plugin_id,
  1272. $sitepress, $sitepress_settings;
  1273. if(!$recursion){
  1274. $icl_st_p_scan_plugin_id = str_replace(WP_PLUGIN_DIR .'/', '', $plugin);
  1275. $icl_st_p_scan_plugin_id = str_replace(WPMU_PLUGIN_DIR .'/', '', $icl_st_p_scan_plugin_id);
  1276. }
  1277. if(is_file($plugin) && !$recursion){ // case of one-file plugins
  1278. $scan_stats = sprintf(__('Scanning file: %s', 'wpml-string-translation'), $plugin) . PHP_EOL;
  1279. _potx_process_file($plugin, 0, '__icl_st_scan_plugin_files_store_results','_potx_save_version', POTX_API_7);
  1280. $scanned_files[] = $plugin;
  1281. }else{
  1282. $dh = opendir($plugin);
  1283. while(false !== ($file = readdir($dh))){
  1284. if(0 === strpos($file, '.')) continue;
  1285. if(is_dir($plugin . "/" . $file)){
  1286. $recursion++;
  1287. $scan_stats .= str_repeat("\t",$recursion-1) . sprintf(__('Opening folder: %s', 'wpml-string-translation'), "/" . $file) . PHP_EOL;
  1288. icl_st_scan_plugin_files($plugin . "/" . $file, $recursion);
  1289. $recursion--;
  1290. }elseif(preg_match('#(\.php|\.inc)$#i', $file)){
  1291. $scan_stats .= str_repeat("\t",$recursion) . sprintf(__('Scanning file: %s', 'wpml-string-translation'), "/" . $file) . PHP_EOL;
  1292. $scanned_files[] = "/" . $file;
  1293. _potx_process_file($plugin . "/" . $file, 0, '__icl_st_scan_plugin_files_store_results','_potx_save_version', POTX_API_7);
  1294. }else{
  1295. $scan_stats .= str_repeat("\t",$recursion) . sprintf(__('Skipping file: %s', 'wpml-string-translation'), "/" . $file) . PHP_EOL;
  1296. }
  1297. }
  1298. }
  1299. if(!$recursion){
  1300. global $__icl_registered_strings;
  1301. if(is_null($__icl_registered_strings)){
  1302. $__icl_registered_strings = array();
  1303. }
  1304. $scan_stats .= __('Done scanning files', 'wpml-string-translation') . PHP_EOL;
  1305. /*
  1306. if(is_array($icl_scan_plugin_found_domains)){
  1307. $existing_domains = $sitepress_settings['st']['plugins_localization_domains'];
  1308. if(is_array($existing_domains)){
  1309. $sitepress_settings['st']['plugins_localization_domains'] = array_unique(array_merge(array_keys($icl_scan_plugin_found_domains), $existing_domains));
  1310. }else{
  1311. $sitepress_settings['st']['plugins_localization_domains'] = array_keys($icl_scan_plugin_found_domains);
  1312. }
  1313. $sitepress->save_settings($sitepress_settings);
  1314. }
  1315. */
  1316. unset($icl_st_p_scan_plugin_id);
  1317. $scan_stats = '<textarea style="width:100%;height:150px;font-size:10px;">' . $scan_stats . "\n" .
  1318. count($scanned_files) . ' scanned files' . "\n";
  1319. if(count($__icl_registered_strings)){
  1320. $scan_stats .= sprintf(__('WPML found %s strings. They were added to the string translation table.','wpml-string-translation'),count($__icl_registered_strings)) . "\n";
  1321. }else{
  1322. $scan_stats .= __('No strings found.','wpml-string-translation') . "\n";
  1323. }
  1324. $scan_stats .= '</textarea>';
  1325. $scan_stats_ret = $scan_stats;
  1326. $scan_stats = false;
  1327. return $scan_stats_ret;
  1328. }
  1329. }
  1330. function __icl_st_scan_plugin_files_store_results($string, $domain, $_gettext_context, $file, $line){
  1331. global $icl_scan_plugin_found_domains, $icl_st_p_scan_plugin_id;
  1332. $string = str_replace(array('\"',"\\'"), array('"',"'"), $string);
  1333. //replace extra backslashes added by _potx_process_file
  1334. $string = str_replace(array('\\\\'), array('\\'), $string);
  1335. //if(!isset($icl_scan_plugin_found_domains[$domain])){
  1336. // $icl_scan_plugin_found_domains[$domain] = true;
  1337. //}
  1338. global $wpdb, $__icl_registered_strings;
  1339. if(empty($__icl_registered_strings) ){
  1340. $__icl_registered_strings = array();
  1341. // clear existing entries (both source and page type)
  1342. $context = $icl_st_p_scan_plugin_id ? 'plugin ' . $icl_st_p_scan_plugin_id : 'plugins';
  1343. $wpdb->query("DELETE FROM {$wpdb->prefix}icl_string_positions WHERE string_id IN
  1344. (SELECT id FROM {$wpdb->prefix}icl_strings WHERE context = '{$context}')");
  1345. }
  1346. if(!isset($__icl_registered_strings[$icl_st_p_scan_plugin_id.'||'.$string])){
  1347. if(!$domain){
  1348. icl_register_string('plugins', md5($string), $string);
  1349. }else{
  1350. icl_register_string('plugin ' . $icl_st_p_scan_plugin_id, md5($string), $string);
  1351. }
  1352. $__icl_registered_strings[$icl_st_p_scan_plugin_id.'||'.$string] = true;
  1353. }
  1354. // store position in source
  1355. icl_st_track_string($string, 'plugin ' . $icl_st_p_scan_plugin_id, ICL_STRING_TRANSLATION_STRING_TRACKING_TYPE_SOURCE, $file, $line);
  1356. }
  1357. function get_theme_localization_stats(){
  1358. global $sitepress_settings, $wpdb;
  1359. $stats = false;
  1360. if(isset($sitepress_settings['st']['theme_localization_domains'])){
  1361. foreach((array)$sitepress_settings['st']['theme_localization_domains'] as $domain){
  1362. $domains[] = $domain ? 'theme ' . $domain : 'theme';
  1363. }
  1364. $results = $wpdb->get_results("
  1365. SELECT context, status, COUNT(id) AS c
  1366. FROM {$wpdb->prefix}icl_strings
  1367. WHERE context IN ('".join("','",$domains)."')
  1368. GROUP BY context, status
  1369. ");
  1370. foreach($results as $r){
  1371. if(!isset($stats[$r->context]['complete'])){
  1372. $stats[$r->context]['complete'] = 0;
  1373. }
  1374. if(!isset($stats[$r->context]['incomplete'])){
  1375. $stats[$r->context]['incomplete'] = 0;
  1376. }
  1377. if($r->status == ICL_STRING_TRANSLATION_COMPLETE){
  1378. $stats[$r->context]['complete'] = $r->c;
  1379. }else{
  1380. $stats[$r->context]['incomplete'] += $r->c;
  1381. }
  1382. }
  1383. }
  1384. return $stats;
  1385. }
  1386. function get_plugin_localization_stats(){
  1387. global $sitepress_settings, $wpdb;
  1388. $stats = false;
  1389. $results = $wpdb->get_results("
  1390. SELECT context, status, COUNT(id) AS c
  1391. FROM {$wpdb->prefix}icl_strings
  1392. WHERE context LIKE ('plugin %')
  1393. GROUP BY context, status
  1394. ");
  1395. foreach($results as $r){
  1396. if(!isset($stats[$r->context]['complete'])){
  1397. $stats[$r->context]['complete'] = 0;
  1398. }
  1399. if(!isset($stats[$r->context]['incomplete'])){
  1400. $stats[$r->context]['incomplete'] = 0;
  1401. }
  1402. if($r->status == ICL_STRING_TRANSLATION_COMPLETE){
  1403. $stats[$r->context]['complete'] = $r->c;
  1404. }else{
  1405. $stats[$r->context]['incomplete'] += $r->c;
  1406. }
  1407. }
  1408. return $stats;
  1409. }
  1410. function icl_st_generate_po_file($strings, $potonly = false){
  1411. global $wpdb;
  1412. $po = "";
  1413. $po .= '# This file was generated by WPML' . PHP_EOL;
  1414. $po .= '# WPML is a WordPress plugin that can turn any WordPress or WordPressMU site into a full featured multilingual content management system.' . PHP_EOL;
  1415. $po .= '# http://wpml.org' . PHP_EOL;
  1416. $po .= 'msgid ""' . PHP_EOL;
  1417. $po .= 'msgstr ""' . PHP_EOL;
  1418. $po .= '"Content-Type: text/plain; charset=utf-8\n"' . PHP_EOL;
  1419. $po .= '"Content-Transfer-Encoding: 8bit\n"' . PHP_EOL;
  1420. $po .= '"Project-Id-Version: \n"' . PHP_EOL;
  1421. $po .= '"POT-Creation-Date: \n"' . PHP_EOL;
  1422. $po .= '"PO-Revision-Date: \n"' . PHP_EOL;
  1423. $po .= '"Last-Translator: \n"' . PHP_EOL;
  1424. $po .= '"Language-Team: \n"' . PHP_EOL;
  1425. $po .= '"MIME-Version: 1.0\n"' . PHP_EOL;
  1426. foreach($strings as $s){
  1427. $ids[] = $s['string_id'];
  1428. }
  1429. if(!empty($ids)){
  1430. $res = $wpdb->get_results("
  1431. SELECT string_id, position_in_page
  1432. FROM {$wpdb->prefix}icl_string_positions
  1433. WHERE kind = " . ICL_STRING_TRANSLATION_STRING_TRACKING_TYPE_SOURCE . " AND string_id IN(".join(',',$ids).")");
  1434. foreach($res as $row){
  1435. $positions[$row->string_id] = $row->position_in_page;
  1436. }
  1437. }
  1438. foreach($strings as $s){
  1439. $po .= PHP_EOL;
  1440. if(!$potonly && isset($s['translations']) && isset($s['translations'][key($s['translations'])]['value'])){
  1441. $translation = $s['translations'][key($s['translations'])]['value'];
  1442. if($translation != '' && $s['translations'][key($s['translations'])]['status'] != ICL_STRING_TRANSLATION_COMPLETE){
  1443. $po .= '#, fuzzy' . PHP_EOL;
  1444. }
  1445. }else{
  1446. $translation = '';
  1447. }
  1448. if(isset($positions[$s['string_id']])){
  1449. $exp = @explode('::',$positions[$s['string_id']]);
  1450. $file = @file($exp[0]);
  1451. }
  1452. $po .= '# ' . @trim($file[$exp[1]-2]) . PHP_EOL;
  1453. $po .= '# ' . @trim($file[$exp[1]-1]) . PHP_EOL;
  1454. $po .= '# ' . @trim($file[$exp[1]]) . PHP_EOL;
  1455. $po .= 'msgid "'.str_replace('"', '\"', $s['value']).'"' . PHP_EOL;
  1456. $po .= 'msgstr "'.str_replace('"', '\"', $translation).'"' . PHP_EOL;
  1457. }
  1458. return $po;
  1459. }
  1460. function icl_st_track_string($text, $context, $kind = ICL_STRING_TRANSLATION_STRING_TRACKING_TYPE_PAGE, $file = null, $line = null){
  1461. global $wpdb;
  1462. // get string id
  1463. $string_id = $wpdb->get_var("SELECT id FROM {$wpdb->prefix}icl_strings WHERE context='".$wpdb->escape($context)."' AND value='".$wpdb->escape($text)."'");
  1464. if($string_id){
  1465. // get existing records
  1466. $string_records_count = $wpdb->get_var("SELECT COUNT(id)
  1467. FROM {$wpdb->prefix}icl_string_positions
  1468. WHERE string_id = '{$string_id}' AND kind = " . $kind);
  1469. if(ICL_STRING_TRANSLATION_STRING_TRACKING_THRESHOLD > $string_records_count){
  1470. if($kind == ICL_STRING_TRANSLATION_STRING_TRACKING_TYPE_PAGE){
  1471. // get page url
  1472. $https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's':'';
  1473. $position = 'http' . $https . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  1474. }else{
  1475. $position = $file . '::' . $line;
  1476. }
  1477. if(!$wpdb->get_var("SELECT id FROM {$wpdb->prefix}icl_string_positions
  1478. WHERE string_id='{$string_id}' AND position_in_page='".$wpdb->escape($position)."' AND kind='".$kind."'")){
  1479. $wpdb->insert($wpdb->prefix . 'icl_string_positions', array(
  1480. 'string_id' => $string_id,
  1481. 'kind' => $kind,
  1482. 'position_in_page' => $position
  1483. ));
  1484. }
  1485. }
  1486. }
  1487. }
  1488. function icl_st_string_in_page($string_id){
  1489. global $wpdb;
  1490. // get urls
  1491. $urls = $wpdb->get_col($wpdb->prepare("SELECT position_in_page
  1492. FROM {$wpdb->prefix}icl_string_positions
  1493. WHERE string_id = %d AND kind = %d", $string_id, ICL_STRING_TRANSLATION_STRING_TRACKING_TYPE_PAGE));
  1494. if(!empty($urls)){
  1495. $string = $wpdb->get_row($wpdb->prepare("SELECT context, value FROM {$wpdb->prefix}icl_strings WHERE id=%d", $string_id));
  1496. echo '<div id="icl_show_source_top">';
  1497. for($i = 0; $i < count($urls); $i++){
  1498. $c = $i+1;
  1499. if(strpos($urls[$i], '?') !== false){
  1500. $urls[$i] .= '&icl_string_track_value=' . urlencode($string->value);
  1501. }else{
  1502. $urls[$i] .= '?icl_string_track_value=' . urlencode($string->value);
  1503. }
  1504. $urls[$i] .= '&icl_string_track_context=' . urlencode($string->context);
  1505. echo '<a href="#" onclick="jQuery(\'#icl_string_track_frame_wrap iframe\').attr(\'src\',\''.$urls[$i].'\');jQuery(\'#icl_string_track_url a\').html(\''.$urls[$i].'\').attr(\'href\', \''.$urls[$i].'\'); return false;">'.$c.'</a><br />';
  1506. }
  1507. echo '</div>';
  1508. echo '<div id="icl_string_track_frame_wrap">';
  1509. echo '<iframe onload="iclResizeIframe()" src="'.$urls[0].'" width="10" height="10" frameborder="0" marginheight="0" marginwidth="0"></iframe>';
  1510. echo '<div id="icl_string_track_url" class="icl_string_track_url"><a href="'.$urls[0].'">' . htmlspecialchars($urls[0]) . "</a></div>\n";
  1511. echo '</div>';
  1512. }else{
  1513. _e('No records found', 'wpml-string-translation');
  1514. }
  1515. }
  1516. function icl_st_string_in_source($string_id){
  1517. global $wpdb, $sitepress_settings;
  1518. // get positions
  1519. $files = $wpdb->get_col($wpdb->prepare("SELECT position_in_page
  1520. FROM {$wpdb->prefix}icl_string_positions
  1521. WHERE string_id = %d AND kind = %d", $string_id, ICL_STRING_TRANSLATION_STRING_TRACKING_TYPE_SOURCE));
  1522. if(!empty($files)){
  1523. $string = $wpdb->get_row($wpdb->prepare("SELECT context, value FROM {$wpdb->prefix}icl_strings WHERE id=%d",$string_id));
  1524. echo '<div id="icl_show_source_top">';
  1525. for($i = 0; $i < count($files); $i++){
  1526. $c = $i+1;
  1527. $exp = explode('::', $files[$i]);
  1528. $line = $exp[1];
  1529. echo '<a href="#" onclick="icl_show_in_source('.$i.','.$line.')">'.$c.'</a><br />';
  1530. }
  1531. echo '</div>';
  1532. echo '<div id="icl_show_source_wrap">';
  1533. for($i = 0; $i < count($files); $i++){
  1534. $exp = explode('::', $files[$i]);
  1535. $file = $exp[0];
  1536. if(!file_exists($file) || !is_readable($file)) continue;
  1537. $line = $exp[1];
  1538. echo '<div class="icl_string_track_source" id="icl_string_track_source_'.$i.'"';
  1539. if($i > 0){
  1540. echo 'style="display:none"';
  1541. }else{
  1542. $first_pos = $line;
  1543. }
  1544. echo '>';
  1545. if($i == 0){
  1546. echo '<script type="text/javascript">icl_show_in_source_scroll_once = ' . $line . '</script>';
  1547. }
  1548. echo '<div class="icl_string_track_filename">' . $file . "</div>\n";
  1549. echo '<pre>';
  1550. $content = file($file);
  1551. echo '<ol>';
  1552. $hl_color = !empty($sitepress_settings['st']['hl_color'])?$sitepress_settings['st']['hl_color']:'#FFFF00';
  1553. foreach($content as $k=>$l){
  1554. if($k == $line-1){
  1555. $hl = ' style="background-color:'.$hl_color.';"';
  1556. }else{
  1557. $hl = '';
  1558. }
  1559. echo '<li id="icl_source_line_'.$i.'_'.$k.'"'.$hl.'">' . htmlspecialchars($l) . '&nbsp;</li>';
  1560. }
  1561. echo '</ol>';
  1562. echo '</pre>';
  1563. echo '</div>';
  1564. }
  1565. echo '</div>';
  1566. }else{
  1567. _e('No records found', 'wpml-string-translation');
  1568. }
  1569. }
  1570. function _icl_st_hide_random($str){
  1571. $str = preg_replace('#^((.+)( - ))?([a-z0-9]{32})$#', '$2', $str);
  1572. return $str;
  1573. }
  1574. function _icl_st_get_options_writes($path){
  1575. static $found_writes = array();
  1576. if(is_dir($path)){
  1577. $dh = opendir($path);
  1578. while($file = readdir($dh)){
  1579. if($file=="." || $file=="..") continue;
  1580. if(is_dir($path . '/' . $file)){
  1581. _icl_st_get_options_writes($path . '/' . $file);
  1582. }elseif(preg_match('#(\.php|\.inc)$#i', $file)){
  1583. $content = file_get_contents($path . '/' . $file);
  1584. $int = preg_match_all('#(add|update)_option\(([^,]+),([^)]+)\)#im', $content, $matches);
  1585. if($int){
  1586. foreach($matches[2] as $m){
  1587. $option_name = trim($m);
  1588. if(0 === strpos($option_name, '"') || 0 === strpos($option_name, "'")){
  1589. $option_name = trim($option_name, "\"'");
  1590. }elseif(false === strpos($option_name, '$')){
  1591. if(false !== strpos($option_name, '::')){
  1592. $cexp = explode('::', $option_name);
  1593. if (class_exists($cexp[0])){
  1594. if (defined($cexp[0].'::'. $cexp[1])){
  1595. $option_name = constant($cexp[0].'::'. $cexp[1]);
  1596. }
  1597. }
  1598. }else{
  1599. if (defined( $option_name )){
  1600. $option_name = constant($option_name);
  1601. }
  1602. }
  1603. }else{
  1604. $option_name = false;
  1605. }
  1606. if($option_name){
  1607. $found_writes[] = $option_name;
  1608. }
  1609. }
  1610. }
  1611. }
  1612. }
  1613. }
  1614. return $found_writes;
  1615. }
  1616. function icl_st_scan_options_strings(){
  1617. global $wpdb;
  1618. $options = array();
  1619. // scan theme php file for update_option(), add_option()
  1620. $options_names = _icl_st_get_options_writes(get_template_directory());
  1621. $options_names = array_merge($options_names, _icl_st_get_options_writes(get_stylesheet_directory()));
  1622. $options_names = array_unique($options_names);
  1623. $options_names = array_map('mysql_real_escape_string', $options_names);
  1624. if(!empty($options_names)){
  1625. $res = $wpdb->get_results("SELECT option_name, option_value FROM $wpdb->options WHERE option_name IN ('".join("','", $options_names)."')");
  1626. foreach($res as $row){
  1627. $options[$row->option_name] = maybe_unserialize($row->option_value);
  1628. // try unserializing twice - just in case (see Arras Theme)
  1629. $options[$row->option_name] = maybe_unserialize($options[$row->option_name]);
  1630. }
  1631. }
  1632. $_icl_admin_option_names = get_option('_icl_admin_option_names', array());
  1633. $_icl_admin_option_names = @array_merge_recursive($_icl_admin_option_names, $options_names);
  1634. $_icl_admin_option_names = __array_unique_recursive($_icl_admin_option_names);
  1635. update_option('_icl_admin_option_names', $_icl_admin_option_names);
  1636. return $options;
  1637. }
  1638. function icl_st_render_option_writes($option_name, $option_value, $option_key=''){
  1639. $has_translations = '';
  1640. if(is_array($option_value) || is_object($option_value)){
  1641. echo '<h4><a class="icl_stow_toggler" href="#">- ' . $option_name . '</a></h4>';
  1642. echo '<ul class="icl_st_option_writes">';
  1643. foreach($option_value as $key=>$value){
  1644. echo '<li>';
  1645. icl_st_render_option_writes($key, $value, $option_key . '[' . $option_name . ']');
  1646. echo '</li>';
  1647. }
  1648. echo '</ul>';
  1649. }elseif(is_string($option_value) || is_numeric($option_value)){
  1650. if(icl_st_is_registered_string('admin_texts_theme_' . get_option('template'), $option_key . $option_name)){
  1651. $checked = ' checked="checked"';
  1652. if(icl_st_string_has_translations('admin_texts_theme_' . get_option('template'), $option_key . $option_name)){
  1653. $has_translations = ' class="icl_st_has_translations"';
  1654. }else{
  1655. $has_translations = '';
  1656. }
  1657. }else{
  1658. $checked = '';
  1659. }
  1660. if(is_numeric($option_value)){
  1661. $class = 'icl_st_numeric';
  1662. }else{
  1663. $class = 'icl_st_string';
  1664. }
  1665. global $iclTranslationManagement;
  1666. $int = preg_match_all('#\[([^\]]+)\]#', $option_key.'['.$option_name.']', $matches);
  1667. $_v = $iclTranslationManagement->admin_texts_to_translate;
  1668. if($int){
  1669. foreach($matches[1] as $m){
  1670. if(isset($_v[$m])){
  1671. $_v = $_v[$m];
  1672. }else{
  1673. $_v = 0;
  1674. break;
  1675. }
  1676. }
  1677. }
  1678. if($_v){
  1679. $disabled = ' disabled="disabled"';
  1680. }else{
  1681. $disabled = '';
  1682. }
  1683. echo '<div class="icl_st_admin_string '.$class.'">';
  1684. echo '<input'.$disabled.' type="hidden" name="icl_admin_options'.$option_key.'['.$option_name.']" value="" />';
  1685. echo '<input'.$disabled.$has_translations.' type="checkbox" name="icl_admin_options'.$option_key.'['.$option_name.']" value="'.htmlspecialchars($option_value).'"
  1686. '.$checked.' />';
  1687. echo '<input type="text" readonly="readonly" value="'.$option_name.'" size="32" />';
  1688. echo '<input type="text" value="'.htmlspecialchars($option_value).'" readonly="readonly" size="48" />';
  1689. //echo '<br /><input type="text" size="100" value="icl_admin_options'.$option_key.'['.$option_name.']" />';
  1690. echo '</div><br clear="all" />';
  1691. }
  1692. }
  1693. function icl_register_admin_options($array, $key=""){
  1694. foreach($array as $k=>$v){
  1695. if(is_array($v)){
  1696. icl_register_admin_options($v, $key . '['.$k.']');
  1697. }else{
  1698. if($v === ''){
  1699. icl_unregister_string('admin_texts_theme_' . get_option('template'), $key . $k);
  1700. }else{
  1701. icl_register_string('admin_texts_theme_' . get_option('template'), $key . $k, $v);
  1702. $int = preg_match_all('#\[([^\]]+)\]#', $key, $matches);
  1703. $vals = array();
  1704. if(count($matches[1]) > 0){
  1705. $vals[] = $k;
  1706. for($i = count($matches[1]) - 1; $i >= 0 ; $i--){
  1707. $tmp = $vals;
  1708. unset($vals);
  1709. $vals[$matches[1][$i]] = $tmp;
  1710. }
  1711. }else{
  1712. $vals[0] = $k;
  1713. }
  1714. $_icl_admin_option_names = get_option('_icl_admin_option_names');
  1715. $_icl_admin_option_names['theme'][get_option('template')] =
  1716. array_merge_recursive((array)$_icl_admin_option_names['theme'][get_option('template')], $vals);
  1717. $_icl_admin_option_names['theme'][get_option('template')] = __array_unique_recursive($_icl_admin_option_names['theme'][get_option('template')]);
  1718. update_option('_icl_admin_option_names', $_icl_admin_option_names);
  1719. }
  1720. }
  1721. }
  1722. }
  1723. function __array_unique_recursive($array){
  1724. $scalars = array();
  1725. foreach($array as $key=>$value){
  1726. if(is_scalar($value)){
  1727. if(isset($scalars[$value])){
  1728. unset($array[$key]);
  1729. }else{
  1730. $scalars[$value] = true;
  1731. }
  1732. }elseif(is_array($value)){
  1733. $array[$key] = __array_unique_recursive($value);
  1734. }
  1735. }
  1736. return $array;
  1737. }
  1738. function _icl_st_filter_empty_options_out($array){
  1739. $empty_found = false;
  1740. foreach($array as $k=>$v){
  1741. if(is_array($v) && !empty($v)){
  1742. list($array[$k], $empty_found) = _icl_st_filter_empty_options_out($v);
  1743. }else{
  1744. if(empty($v)){
  1745. unset($array[$k]);
  1746. $empty_found = true;
  1747. }
  1748. }
  1749. }
  1750. return array($array, $empty_found);
  1751. }
  1752. function wpml_register_admin_strings($serialized_array){
  1753. try{
  1754. icl_register_admin_options(unserialize($serialized_array));
  1755. }catch(Exception $e){
  1756. trigger_error($e->getMessage(), E_USER_WARNING);
  1757. }
  1758. }
  1759. add_action('plugins_loaded', 'icl_st_set_admin_options_filters', 10);
  1760. function icl_st_set_admin_options_filters(){
  1761. $option_names = get_option('_icl_admin_option_names');
  1762. if(!empty($option_names['theme']) && !empty($option_names['theme'][basename(get_template_directory())])){
  1763. foreach($option_names['theme'][basename(get_template_directory())] as $option_key=>$option){
  1764. if(is_array($option) || is_object($option)){
  1765. add_filter('option_'.$option_key, 'icl_st_translate_admin_string');
  1766. }else{
  1767. add_filter('option_'.$option, 'icl_st_translate_admin_string');
  1768. }
  1769. }
  1770. if(get_template_directory() != get_stylesheet_directory() && !empty($option_names['theme'][basename(get_stylesheet_directory())])){
  1771. foreach((array)$option_names['theme'][basename(get_stylesheet_directory())] as $option_key=>$option){
  1772. if(is_array($option) || is_object($option)){
  1773. add_filter('option_'.$option_key, 'icl_st_translate_admin_string');
  1774. }else{
  1775. add_filter('option_'.$option, 'icl_st_translate_admin_string');
  1776. }
  1777. }
  1778. }
  1779. }
  1780. if(!empty($option_names['plugin'])){
  1781. foreach($option_names['plugin'] as $plugin => $options){
  1782. foreach((array)$options as $option_key => $option){
  1783. if(is_array($option) || is_object($option)){
  1784. add_filter('option_'.$option_key, 'icl_st_translate_admin_string');
  1785. }else{
  1786. add_filter('option_'.$option, 'icl_st_translate_admin_string');
  1787. }
  1788. }
  1789. }
  1790. }
  1791. }
  1792. function icl_st_translate_admin_string($option_value, $key="", $name="", $rec_level = 0){
  1793. // determine option name
  1794. if(!$name){
  1795. if(is_array($option_value) || is_object($option_value)){
  1796. $ob = debug_backtrace();
  1797. if(is_scalar($ob[3]['args'][0])){
  1798. $name = preg_replace('@^option_@', '', $ob[3+$rec_level]['args'][0]);
  1799. }
  1800. }else{
  1801. $ob = debug_backtrace();
  1802. if(is_scalar($ob[2+$rec_level]['args'][0])){
  1803. $name = preg_replace('@^option_@', '',$ob[2+$rec_level]['args'][0]);
  1804. }
  1805. }
  1806. }
  1807. // cache - phase 1 - check/get
  1808. static $__icl_st_cache;
  1809. if($rec_level == 0){
  1810. if(isset($__icl_st_cache[$name])) {
  1811. //echo "FROM CACHE $name<br />";
  1812. return $__icl_st_cache[$name];
  1813. }
  1814. }
  1815. // case of double-serialized options (See Arras theme)
  1816. $serialized = false;
  1817. if(is_serialized( $option_value )){
  1818. $option_value = @unserialize($option_value);
  1819. $serialized = true;
  1820. }
  1821. //if(is_object($option_value)){
  1822. //$option_value = (array)$option_value;
  1823. //}
  1824. if(is_array($option_value) || is_object($option_value)){
  1825. foreach($option_value as $k=>$value){
  1826. $val = icl_st_translate_admin_string($value, $key . '[' . $name . ']' , $k, $rec_level+1);
  1827. if(is_object($option_value)){
  1828. $option_value->$k = $val;
  1829. }else{
  1830. $option_value[$k] = $val;
  1831. }
  1832. }
  1833. }else{
  1834. $option_names = get_option('_icl_admin_option_names');
  1835. // determine theme/plugin name
  1836. if(!empty($option_names['theme'])){
  1837. foreach((array)$option_names['theme'][basename(get_template_directory())] as $ops=>$val){
  1838. if(!empty($key)){
  1839. $int = preg_match_all('#\[([^\]]+)\]#', $key, $matches);
  1840. if($int) $opname = $matches[1][0];
  1841. }else{
  1842. $opname = $name;
  1843. }
  1844. if($ops == $opname){
  1845. $key_suff = 'theme_' . basename(get_template_directory());
  1846. break;
  1847. }
  1848. }
  1849. if(get_template_directory() != get_stylesheet_directory()){
  1850. foreach((array)$option_names['theme'][basename(get_stylesheet_directory())] as $ops=>$val){
  1851. if(!empty($key)){
  1852. $int = preg_match_all('#\[([^\]]+)\]#', $key, $matches);
  1853. if($int) $opname = $matches[1][0];
  1854. }else{
  1855. $opname = $name;
  1856. }
  1857. if($ops == $opname){
  1858. $key_suff = 'theme_' . get_stylesheet_directory();
  1859. break;
  1860. }
  1861. }
  1862. }
  1863. }
  1864. if(!empty($option_names['plugin'])){
  1865. foreach((array)$option_names['plugin'] as $plugin => $options){
  1866. foreach($options as $kops=>$ops){
  1867. if(is_array($ops)){
  1868. $arrkey = explode('][', trim($key, '[]'));
  1869. $_val = $options;
  1870. for($i=0; $i<count($arrkey); $i++){
  1871. if(isset($_val[$arrkey[$i]])){
  1872. $_val = $_val[$arrkey[$i]];
  1873. }else{
  1874. break;
  1875. }
  1876. }
  1877. if(in_array($name, $_val)){
  1878. $key_suff = 'plugin_' . $plugin;
  1879. break;
  1880. }
  1881. }elseif($ops == $name){
  1882. $key_suff = 'plugin_' . $plugin;
  1883. break;
  1884. }
  1885. }
  1886. }
  1887. }
  1888. if(!empty($key_suff)){
  1889. $tr = icl_t('admin_texts_' . $key_suff, $key . $name, $option_value, $hast, true);
  1890. }
  1891. if(isset($tr)){
  1892. $option_value = $tr;
  1893. }
  1894. }
  1895. // case of double-serialized options (See Arras theme)
  1896. if($serialized){
  1897. $option_value = serialize($option_value);
  1898. }
  1899. // cache - phase 2 - set
  1900. if($rec_level == 0){
  1901. $__icl_st_cache[$name] = $option_value;
  1902. }
  1903. return $option_value;
  1904. }
  1905. function icl_st_get_mo_files($path){
  1906. static $mo_files = array();
  1907. if(is_readable($path)){
  1908. $dh = opendir($path);
  1909. while($f = readdir($dh)){
  1910. if(0 !== strpos($f, '.')){
  1911. if(is_dir($path . '/' . $f)){
  1912. icl_st_get_mo_files($path . '/' . $f);
  1913. }else{
  1914. if(preg_match('#\.mo$#', $f)){
  1915. $mo_files[] = $path . '/' . $f;
  1916. }
  1917. }
  1918. }
  1919. }
  1920. }
  1921. return $mo_files;
  1922. }
  1923. function icl_st_load_translations_from_mo($mo_file){
  1924. $translations = array();
  1925. $mo = new MO();
  1926. $mo->import_from_file( $mo_file );
  1927. foreach($mo->entries as $str=>$v){
  1928. $str = str_replace("\n",'\n', $str);
  1929. $translations[$str] = $v->translations[0];
  1930. }
  1931. return $translations;
  1932. }
  1933. // fix links in existing strings according to the new translation added
  1934. function icl_st_fix_links_in_strings($post_id){
  1935. static $runnonce = false;
  1936. if($runnonce){
  1937. return;
  1938. }
  1939. $runonce = true;
  1940. if(isset($_POST['autosave']) && $_POST['autosave']) return;
  1941. if(isset($_POST['post_ID'])){
  1942. $post_id = $_POST['post_ID'];
  1943. }
  1944. global $wpdb, $sitepress;
  1945. $language = $wpdb->get_var($wpdb->prepare("SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_type='post' AND element_id=%d", $post_id));
  1946. if($language){
  1947. if($sitepress->get_default_language()==$language){
  1948. $strings = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->prefix}icl_strings WHERE language=%s",$language));
  1949. }else{
  1950. $strings = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->prefix}icl_string_translations WHERE language=%s",$language));
  1951. }
  1952. foreach($strings as $string_id){
  1953. _icl_content_fix_links_to_translated_content($string_id, $language, 'string');
  1954. }
  1955. }
  1956. }
  1957. function icl_translation_send_strings($string_ids, $target_languages) {
  1958. global $WPML_String_Translation;
  1959. $errors = 0;
  1960. // send to each language
  1961. foreach($target_languages as $target=>$service){
  1962. if($service == 'icanlocalize'){
  1963. if( !_icl_translation_send_strings_icanlocalize($string_ids, $target, $service) ) $errors++;
  1964. }elseif($service == 'local'){
  1965. if( ! _icl_translation_send_strings_local($string_ids, $target, $service) ) $errors++;
  1966. }
  1967. }
  1968. if($errors == count($target_languages)){
  1969. $WPML_String_Translation->add_message(__('No string was sent to translation.','wpml-string-translation'), 'error');
  1970. }elseif($errors > 0){
  1971. $WPML_String_Translation->add_message(__('Some strings were not sent to translation.','wpml-string-translation'), 'error');
  1972. }else{
  1973. if(count($string_ids) > 1){
  1974. $WPML_String_Translation->add_message(__('All strings were sent to translation.','wpml-string-translation'));
  1975. }else{
  1976. $WPML_String_Translation->add_message(__('The string was sent to translation.','wpml-string-translation'));
  1977. }
  1978. }
  1979. }
  1980. function _icl_translation_send_strings_local($string_ids, $target) {
  1981. global $wpdb, $sitepress_settings;
  1982. static $site_translators;
  1983. $site_translators = TranslationManagement::get_blog_translators();
  1984. $mkey = $wpdb->prefix . 'strings_notification';
  1985. $lkey = $wpdb->prefix . 'language_pairs';
  1986. $slang =& $sitepress_settings['st']['strings_language'];
  1987. foreach($string_ids as $string_id) {
  1988. $added = icl_add_string_translation($string_id, $target, NULL , ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR);
  1989. if($added)
  1990. foreach($site_translators as $key=>$st){
  1991. $ulangs = isset($st->$lkey) ? $st->$lkey : false;
  1992. if(!empty($ulangs) && !empty($ulangs[$slang][$target])){
  1993. $enot = isset($st->$mkey) ? $st->$mkey : false;
  1994. if(empty($enot[$sitepress_settings['st']['strings_language']][$target])){
  1995. _icl_st_translator_notification($st, $sitepress_settings['st']['strings_language'], $target);
  1996. $enot[$sitepress_settings['st']['strings_language']][$target] = 1;
  1997. $site_translators[$key]->$mkey = $enot;
  1998. update_option($wpdb->prefix . 'icl_translators_cached', $site_translators);
  1999. //printf("Notify %d for %s -> %s <br />", $st->ID, $sitepress_settings['st']['strings_language'], $target);
  2000. }else{
  2001. //printf("Already notified %d for %s -> %s <br />", $st->ID, $sitepress_settings['st']['strings_language'], $target);
  2002. }
  2003. }
  2004. }
  2005. }
  2006. return 1;
  2007. }
  2008. function _icl_st_translator_notification($user, $source, $target){
  2009. global $wpdb, $sitepress;
  2010. $_ldetails = $sitepress->get_language_details($source);
  2011. $source_en = $_ldetails['english_name'];
  2012. $_ldetails = $sitepress->get_language_details($target);
  2013. $target_en = $_ldetails['english_name'];
  2014. $message = "You have been assigned to new translation job from %s to %s.
  2015. Start editing: %s
  2016. You can view your other translation jobs here: %s
  2017. This message was automatically sent by Translation Management running on WPML. To stop receiving these notifications contact the system administrator at %s.
  2018. This email is not monitored for replies.
  2019. - The folks at ICanLocalize
  2020. 101 Convention Center Dr., Las Vegas, Nevada, 89109, USA
  2021. ";
  2022. $to = $user->user_email;
  2023. $subject = sprintf("You have been assigned to new translation job on %s.", get_bloginfo('name'));
  2024. $body = sprintf($message,
  2025. $source_en, $target_en, admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php'),
  2026. admin_url('admin.php?page='.WPML_TM_FOLDER.'/menu/translations-queue.php'), home_url());
  2027. wp_mail($to, $subject, $body);
  2028. $meta = get_user_meta($user->ID, $wpdb->prefix . 'strings_notification', 1);
  2029. $meta[$source][$target] = 1;
  2030. update_user_meta($user->ID, $wpdb->prefix . 'strings_notification', $meta);
  2031. }
  2032. function icl_st_reset_current_trasnslator_notifications(){
  2033. global $current_user, $wpdb;
  2034. $mkey = $wpdb->prefix . 'strings_notification';
  2035. if(!empty($current_user->$mkey)){
  2036. update_user_meta(get_current_user_id(), $mkey, array());
  2037. }
  2038. }
  2039. function _icl_translation_send_strings_icanlocalize($string_ids, $target) {
  2040. global $wpdb, $sitepress, $sitepress_settings;
  2041. if(!$sitepress_settings['st']['strings_language'])
  2042. $sitepress_settings['st']['strings_language'] = $sitepress->get_default_language();
  2043. $target_details = $sitepress->get_language_details($target);
  2044. // get all the untranslated strings
  2045. $untranslated = array();
  2046. foreach($string_ids as $st_id) {
  2047. $status = $wpdb->get_var($wpdb->prepare("SELECT status FROM {$wpdb->prefix}icl_string_translations WHERE string_id=%d and language=%s", $st_id, $target));
  2048. if ($status != ICL_STRING_TRANSLATION_COMPLETE) {
  2049. $untranslated[] = $st_id;
  2050. }
  2051. }
  2052. if (sizeof($untranslated) > 0) {
  2053. // Something to translate.
  2054. $target_for_server = array(ICL_Pro_Translation::server_languages_map($target_details['english_name'])); //filter some language names to match the names on the server
  2055. $data = array(
  2056. 'url'=>'',
  2057. 'target_languages' => $target_for_server,
  2058. );
  2059. $string_values = array();
  2060. foreach($untranslated as $st_id) {
  2061. $string = $wpdb->get_row($wpdb->prepare("SELECT context, name, value FROM {$wpdb->prefix}icl_strings WHERE id=%d", $st_id));
  2062. $string_values[$st_id] = $string->value;
  2063. $data['contents']['string-'.$st_id.'-context'] = array(
  2064. 'translate'=>0,
  2065. 'data'=>base64_encode(htmlspecialchars($string->context)),
  2066. 'format'=>'base64',
  2067. );
  2068. $data['contents']['string-'.$st_id.'-name'] = array(
  2069. 'translate'=>0,
  2070. 'data'=>base64_encode(htmlspecialchars($string->name)),
  2071. 'format'=>'base64',
  2072. );
  2073. $data['contents']['string-'.$st_id.'-value'] = array(
  2074. 'translate'=>1,
  2075. 'data'=>base64_encode(htmlspecialchars($string->value)),
  2076. 'format'=>'base64',
  2077. );
  2078. }
  2079. $iclq = new ICanLocalizeQuery($sitepress_settings['site_id'], $sitepress_settings['access_key']);
  2080. $orig_lang = $sitepress->get_language_details($sitepress_settings['st']['strings_language']);
  2081. $orig_lang_for_server = ICL_Pro_Translation::server_languages_map($orig_lang['english_name']);
  2082. $timestamp = date('Y-m-d H:i:s');
  2083. $xml = $iclq->build_cms_request_xml($data, $orig_lang_for_server);
  2084. $args = array(
  2085. 'xml' => $xml,
  2086. 'title' => "String translations",
  2087. 'to_languages' => $target_for_server,
  2088. 'orig_language' => $orig_lang_for_server
  2089. );
  2090. $res = $iclq->send_request($args);
  2091. if($res > 0){
  2092. foreach($string_values as $st_id => $value){
  2093. $wpdb->insert($wpdb->prefix.'icl_string_status',
  2094. array('rid'=>$res, 'string_translation_id'=>$st_id, 'timestamp'=>$timestamp, 'md5'=>md5($value))); //insert rid
  2095. }
  2096. $wpdb->insert($wpdb->prefix.'icl_core_status', array('rid'=>$res,
  2097. 'origin'=>$orig_lang['code'],
  2098. 'target'=>$target,
  2099. 'status'=>CMS_REQUEST_WAITING_FOR_PROJECT_CREATION));
  2100. return $res;
  2101. }else{
  2102. return 0;
  2103. }
  2104. }
  2105. }
  2106. function icl_decode_translation_status_id($status){
  2107. switch($status){
  2108. case CMS_TARGET_LANGUAGE_CREATED: $st = __('Waiting for translator','wpml-string-translation');break;
  2109. case CMS_TARGET_LANGUAGE_ASSIGNED: $st = __('In progress','wpml-string-translation');break;
  2110. case CMS_TARGET_LANGUAGE_TRANSLATED: $st = __('Translation received','wpml-string-translation');break;
  2111. case CMS_TARGET_LANGUAGE_DONE: $st = __('Translation complete','wpml-string-translation');break;
  2112. case CMS_REQUEST_FAILED: $st = __('Request failed','wpml-string-translation');break;
  2113. default: $st = __('Not translated','wpml-string-translation');
  2114. }
  2115. return $st;
  2116. }
  2117. function icl_translation_get_string_translation_status($string_id) {
  2118. global $wpdb;
  2119. $status = $wpdb->get_var($wpdb->prepare("
  2120. SELECT
  2121. MIN(cs.status)
  2122. FROM
  2123. {$wpdb->prefix}icl_core_status cs
  2124. JOIN
  2125. {$wpdb->prefix}icl_string_status ss
  2126. ON
  2127. ss.rid = cs.rid
  2128. WHERE
  2129. ss.string_translation_id=%d
  2130. ", $string_id
  2131. ));
  2132. if ($status === null){
  2133. return "";
  2134. }
  2135. $status = icl_decode_translation_status_id($status);
  2136. return $status;
  2137. }
  2138. function icl_translation_send_untranslated_strings($target_languages) {
  2139. global $wpdb;
  2140. $untranslated = $wpdb->get_col($wpdb->prepare("SELECT id FROM {$wpdb->prefix}icl_strings WHERE status <> %d", ICL_STRING_TRANSLATION_COMPLETE));
  2141. icl_translation_send_strings($untranslated, $target_languages);
  2142. }
  2143. function icl_is_string_translation($translation) {
  2144. // determine if the $translation data is for string translation.
  2145. foreach($translation as $key => $value) {
  2146. if($key == 'body' or $key == 'title') {
  2147. return false;
  2148. }
  2149. if (preg_match("/string-.*?-value/", $key)){
  2150. return true;
  2151. }
  2152. }
  2153. // if we get here assume it's not a string.
  2154. return false;
  2155. }
  2156. function icl_translation_add_string_translation($rid, $translation, $lang_code){
  2157. global $wpdb, $sitepress_settings, $sitepress;
  2158. foreach($translation as $key => $value) {
  2159. if (preg_match("/string-(.*?)-value/", $key, $match)){
  2160. $string_id = $match[1];
  2161. $md5_when_sent = $wpdb->get_var($wpdb->prepare("SELECT md5 FROM {$wpdb->prefix}icl_string_status
  2162. WHERE string_translation_id=%d AND rid=%d", $string_id, $rid));
  2163. $current_string_value = $wpdb->get_var($wpdb->prepare("SELECT value FROM {$wpdb->prefix}icl_strings WHERE id=%d", $string_id));
  2164. if ($md5_when_sent == md5($current_string_value)) {
  2165. $status = ICL_STRING_TRANSLATION_COMPLETE;
  2166. } else {
  2167. $status = ICL_STRING_TRANSLATION_NEEDS_UPDATE;
  2168. }
  2169. $value = str_replace ( '&#0A;', "\n", $value );
  2170. icl_add_string_translation($string_id, $lang_code, html_entity_decode($value), $status, 0);
  2171. }
  2172. }
  2173. // update translation status
  2174. $wpdb->update($wpdb->prefix.'icl_core_status', array('status'=>CMS_TARGET_LANGUAGE_DONE), array('rid'=>$rid, 'target'=>$lang_code));
  2175. return true;
  2176. }
  2177. function icl_st_get_pending_string_translations_stats(){
  2178. global $wpdb, $current_user, $sitepress_settings;
  2179. get_currentuserinfo();
  2180. $user_lang_pairs = get_user_meta($current_user->ID, $wpdb->prefix.'language_pairs', true);
  2181. $stats = array();
  2182. if(!empty($user_lang_pairs[$sitepress_settings['st']['strings_language']])){
  2183. $results = $wpdb->get_results($wpdb->prepare("
  2184. SELECT COUNT(id) AS c, language
  2185. FROM {$wpdb->prefix}icl_string_translations
  2186. WHERE status=%d AND language IN ('".join("','", array_keys($user_lang_pairs[$sitepress_settings['st']['strings_language']]))."')
  2187. AND (translator_id IS NULL or translator_id > 0)
  2188. GROUP BY language
  2189. ORDER BY c DESC
  2190. ",
  2191. ICL_STRING_TRANSLATION_WAITING_FOR_TRANSLATOR
  2192. ));
  2193. foreach($results as $r){
  2194. $_stats[$r->language] = $r->c;
  2195. }
  2196. foreach($user_lang_pairs[$sitepress_settings['st']['strings_language']] as $lang=>$one){
  2197. $stats[$lang] = isset($_stats[$lang]) ? $_stats[$lang] : 0;
  2198. }
  2199. }
  2200. return $stats;
  2201. }
  2202. function icl_st_is_translator(){
  2203. return current_user_can('translate') && !current_user_can('manage_options');
  2204. }
  2205. function icl_st_debug($str){
  2206. trigger_error($str, E_USER_WARNING);
  2207. }