PageRenderTime 87ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/qtranslate/qtranslate_services.php

https://gitlab.com/Blueprint-Marketing/interoccupy.net
PHP | 911 lines | 797 code | 51 blank | 63 comment | 128 complexity | 26d92213c91b919b30b6f86c4ab1ba9e MD5 | raw file
  1. <?php // encoding: utf-8
  2. /* Copyright 2008 Qian Qin (email : mail@qianqin.de)
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  14. */
  15. /* qTranslate Services */
  16. // generate public key
  17. $qs_public_key = '-----BEGIN PUBLIC KEY-----|MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNccmB4Up9V9+vD5kWWiE6zpRV|m7y1sdFihreycdpmu3aPjKooG5LWUbTTyc993nTxV71SKuuYdkPzu5JxniAsI2N0|7DsySZ/bQ2/BEANNwJD3pmz4NmIHgIeNaUze/tvTZq6m+FTVHSvEqAaXJIsQbO19|HeegbfEpmCj1d/CgOwIDAQAB|-----END PUBLIC KEY-----|';
  18. // OpenSSL functions used
  19. $qs_openssl_functions_used = array(
  20. 'openssl_pkey_new',
  21. 'openssl_pkey_export',
  22. 'openssl_pkey_get_details',
  23. 'openssl_seal',
  24. 'openssl_open',
  25. 'openssl_free_key'
  26. );
  27. // check schedule
  28. if (!wp_next_scheduled('qs_cron_hook')) {
  29. wp_schedule_event( time(), 'hourly', 'qs_cron_hook' );
  30. }
  31. define('QS_FAST_TIMEOUT', 10);
  32. define('QS_VERIFY', 'verify');
  33. define('QS_GET_SERVICES', 'get_services');
  34. define('QS_INIT_TRANSLATION', 'init_translation');
  35. define('QS_RETRIEVE_TRANSLATION', 'retrieve_translation');
  36. define('QS_QUOTE', 'quote');
  37. define('QS_STATE_OPEN', 'open');
  38. define('QS_STATE_ERROR', 'error');
  39. define('QS_STATE_CLOSED', 'closed');
  40. define('QS_ERROR_INVALID_LANGUAGE', 'QS_ERROR_INVALID_LANGUAGE');
  41. define('QS_ERROR_NOT_SUPPORTED_LANGUAGE', 'QS_ERROR_NOT_SUPPORTED_LANGUAGE');
  42. define('QS_ERROR_INVALID_SERVICE', 'QS_ERROR_INVALID_SERVICE');
  43. define('QS_ERROR_INVALID_ORDER', 'QS_ERROR_INVALID_ORDER');
  44. define('QS_ERROR_SERVICE_GENERIC', 'QS_ERROR_SERVICE_GENERIC');
  45. define('QS_ERROR_SERVICE_UNKNOWN', 'QS_ERROR_SERVICE_UNKNOWN');
  46. define('QS_DEBUG', 'QS_DEBUG');
  47. // error messages
  48. $qs_error_messages[QS_ERROR_INVALID_LANGUAGE] = __('The language/s do not have a valid ISO 639-1 representation.','qtranslate');
  49. $qs_error_messages[QS_ERROR_NOT_SUPPORTED_LANGUAGE] = __('The language/s you used are not supported by the service.','qtranslate');
  50. $qs_error_messages[QS_ERROR_INVALID_SERVICE] = __('There is no such service.','qtranslate');
  51. $qs_error_messages[QS_ERROR_INVALID_ORDER] = __('The system could not process your order.','qtranslate');
  52. $qs_error_messages[QS_ERROR_SERVICE_GENERIC] = __('There has been an error with the selected service.','qtranslate');
  53. $qs_error_messages[QS_ERROR_SERVICE_UNKNOWN] = __('An unknown error occured with the selected service.','qtranslate');
  54. $qs_error_messages[QS_DEBUG] = __('The server returned a debugging message.','qtranslate');
  55. // hooks
  56. add_action('qtranslate_css', 'qs_css');
  57. add_action('qs_cron_hook', 'qs_cron');
  58. add_action('qtranslate_configuration', 'qs_config_hook');
  59. add_action('qtranslate_loadConfig', 'qs_load');
  60. add_action('qtranslate_saveConfig', 'qs_save');
  61. add_action('qtranslate_clean_uri', 'qs_clean_uri');
  62. add_action('admin_menu', 'qs_init');
  63. add_action('wp_ajax_qs_quote', 'qs_quote');
  64. add_filter('manage_order_columns', 'qs_order_columns');
  65. add_filter('qtranslate_configuration_pre', 'qs_config_pre_hook');
  66. // serializing/deserializing functions
  67. function qs_base64_serialize($var) {
  68. if(is_array($var)) {
  69. foreach($var as $key => $value) {
  70. $var[$key] = qs_base64_serialize($value);
  71. }
  72. }
  73. $var = serialize($var);
  74. $var = strtr(base64_encode($var), '-_,', '+/=');
  75. return $var;
  76. }
  77. function qs_base64_unserialize($var) {
  78. $var = base64_decode(strtr($var, '-_,', '+/='));
  79. $var = unserialize($var);
  80. if(is_array($var)) {
  81. foreach($var as $key => $value) {
  82. $var[$key] = qs_base64_unserialize($value);
  83. }
  84. }
  85. return $var;
  86. }
  87. // sends a encrypted message to qTranslate Services and decrypts the received data
  88. function qs_queryQS($action, $data='', $fast = false) {
  89. global $qs_public_key;
  90. // generate new private key
  91. $key = openssl_pkey_new();
  92. openssl_pkey_export($key, $private_key);
  93. $public_key=openssl_pkey_get_details($key);
  94. $public_key=$public_key["key"];
  95. $message = qs_base64_serialize(array('key'=>$public_key, 'data'=>$data));
  96. openssl_seal($message, $message, $server_key, array($qs_public_key));
  97. $message = qs_base64_serialize(array('key'=>$server_key[0], 'data'=>$message));
  98. $data = "message=".$message;
  99. // connect to qts
  100. if($fast) {
  101. $fp = fsockopen('www.qianqin.de', 80, $errno, $errstr, QS_FAST_TIMEOUT);
  102. stream_set_timeout($fp, QS_FAST_TIMEOUT);
  103. } else {
  104. $fp = fsockopen('www.qianqin.de', 80);
  105. }
  106. if(!$fp) return false;
  107. fputs($fp, "POST /qtranslate/services/$action HTTP/1.1\r\n");
  108. fputs($fp, "Host: www.qianqin.de\r\n");
  109. fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
  110. fputs($fp, "Content-length: ". strlen($data) ."\r\n");
  111. fputs($fp, "Connection: close\r\n\r\n");
  112. fputs($fp, $data);
  113. $res = '';
  114. while(!feof($fp)) {
  115. $res .= fgets($fp, 128);
  116. }
  117. // check for timeout
  118. $info = stream_get_meta_data($fp);
  119. if($info['timed_out']) return false;
  120. fclose($fp);
  121. preg_match("#^Content-Length:\s*([0-9]+)\s*$#ism",$res, $match);
  122. if(isset($match[1])) {
  123. $content_length = $match[1];
  124. $content = substr($res, -$content_length, $content_length);
  125. } else {
  126. $content = $res;
  127. }
  128. $debug = $content;
  129. $content = qs_base64_unserialize($content);
  130. openssl_open($content['data'], $content, $content['key'], $private_key);
  131. if($content===false) {
  132. echo "<pre>DEBUG:\n";
  133. echo $debug;
  134. echo "</pre>";
  135. }
  136. openssl_free_key($key);
  137. return qs_cleanup(qs_base64_unserialize($content), $action);
  138. }
  139. function qs_clean_uri($clean_uri) {
  140. return preg_replace("/&(qs_delete|qs_cron)=[^&#]*/i","",$clean_uri);
  141. }
  142. function qs_translateButtons($available_languages, $missing_languages) {
  143. global $q_config, $post;
  144. if(sizeof($missing_languages)==0) return;
  145. $missing_languages_name = array();
  146. foreach($missing_languages as $language) {
  147. $missing_languages_name[] = '<a href="edit.php?page=qtranslate_services&post='.$post->ID.'&target_language='.$language.'">'.$q_config['language_name'][$language].'</a>';
  148. }
  149. $missing_languages_names = join(', ', $missing_languages_name);
  150. printf(__('<div>Translate to %s</div>', 'qtranslate') ,$missing_languages_names);
  151. }
  152. function qs_css() {
  153. ?>
  154. p.error {background-color:#ffebe8;border-color:#c00;border-width:1px;border-style:solid;padding:0 .6em;margin:5px 15px 2px;-moz-border-radius:3px;-khtml-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;}
  155. p.error a{color:#c00;}
  156. #qs_boxes { margin-right:300px }
  157. #qs_boxes .postbox h3.hndle, #submitboxcontainer .postbox h3.hndle {cursor:auto}
  158. #qs_boxes div.inside {margin: 6px 6px 8px;}
  159. #submitboxcontainer { float:right; width:280px }
  160. #qs_content_preview { width:100%; height:200px }
  161. .service_description { margin-left:20px; margin-top:0 }
  162. #qtranslate-services h4 { margin-top:0 }
  163. #qtranslate-services h5 { margin-bottom:0 }
  164. #qtranslate-services .description { font-size:11px }
  165. #qtrans_select_translate { margin-right:11px }
  166. .qs_status { border:0 }
  167. .qs_no-bottom-border { border-bottom:0 !important }
  168. #submitboxcontainer p { margin:6px 6px ; }
  169. .qs_submit { text-align:right; padding:6px }
  170. <?php
  171. }
  172. function qs_load() {
  173. global $q_config, $qs_public_key;
  174. $qtranslate_services = get_option('qtranslate_qtranslate_services');
  175. $qtranslate_services = qtrans_validateBool($qtranslate_services, $q_config['qtranslate_services']);
  176. $q_config['qtranslate_services'] = $qtranslate_services && qs_isOpenSSLAvailable();
  177. if($q_config['qtranslate_services'] && is_string($qs_public_key)) {
  178. $qs_public_key = openssl_get_publickey(join("\n",explode("|",$qs_public_key)));
  179. }
  180. }
  181. function qs_isOpenSSLAvailable() {
  182. global $qs_openssl_functions_used;
  183. foreach($qs_openssl_functions_used as $function) {
  184. if(!function_exists($function)) return false;
  185. }
  186. return true;
  187. }
  188. function qs_init() {
  189. global $q_config;
  190. if($q_config['qtranslate_services']) {
  191. /* disabled for meta box
  192. add_filter('qtranslate_toolbar', 'qs_toobar');
  193. add_filter('qtranslate_modify_editor_js', 'qs_editor_js');
  194. */
  195. add_meta_box('translatediv', __('Translate to','qtranslate'), 'qs_translate_box', 'post', 'side', 'core');
  196. add_meta_box('translatediv', __('Translate to','qtranslate'), 'qs_translate_box', 'page', 'side', 'core');
  197. add_action('qtranslate_languageColumn', 'qs_translateButtons', 10, 2);
  198. // add plugin page without menu link for users with permission
  199. if(current_user_can('edit_published_posts')) {
  200. //add_posts_page(__('Translate','qtranslate'), __('Translate','qtranslate'), 'edit_published_posts', 'qtranslate_services', 'qs_service');
  201. global $_registered_pages;
  202. $hookname = get_plugin_page_hookname('qtranslate_services', 'edit.php');
  203. add_action($hookname, 'qs_service');
  204. $_registered_pages[$hookname] = true;
  205. }
  206. }
  207. }
  208. function qs_save() {
  209. global $q_config;
  210. if($q_config['qtranslate_services'])
  211. update_option('qtranslate_qtranslate_services', '1');
  212. else
  213. update_option('qtranslate_qtranslate_services', '0');
  214. }
  215. function qs_cleanup($var, $action) {
  216. switch($action) {
  217. case QS_GET_SERVICES:
  218. foreach($var as $service_id => $service) {
  219. // make array out ouf serialized field
  220. $fields = array();
  221. $required_fields = explode('|',$service['service_required_fields']);
  222. foreach($required_fields as $required_field) {
  223. if(strpos($required_field, " ")!==false) {
  224. list($fieldname, $title) = explode(' ', $required_field, 2);
  225. if($fieldname!='') {
  226. $fields[] = array('name' => $fieldname, 'value' => '', 'title' => $title);
  227. }
  228. }
  229. }
  230. $var[$service_id]['service_required_fields'] = $fields;
  231. }
  232. break;
  233. }
  234. if(isset($var['error']) && $var['error'] == QS_DEBUG) {
  235. echo "<pre>Debug message received from Server: \n";
  236. var_dump($var['message']);
  237. echo "</pre>";
  238. }
  239. return $var;
  240. }
  241. function qs_config_pre_hook($message) {
  242. global $q_config;
  243. if(isset($_POST['default_language'])) {
  244. qtrans_checkSetting('qtranslate_services', true, QT_BOOLEAN);
  245. qs_load();
  246. if($q_config['qtranslate_services']) {
  247. $services = qs_queryQS(QS_GET_SERVICES);
  248. $service_settings = get_option('qs_service_settings');
  249. if(!is_array($service_settings)) $service_settings = array();
  250. foreach($services as $service_id => $service) {
  251. // check if there are already settings for the field
  252. if(!isset($service_settings[$service_id])||!is_array($service_settings[$service_id])) $service_settings[$service_id] = array();
  253. // update fields
  254. foreach($service['service_required_fields'] as $field) {
  255. if(isset($_POST['qs_'.$service_id.'_'.$field['name']])) {
  256. // skip empty passwords to keep the old value
  257. if($_POST['qs_'.$service_id.'_'.$field['name']]=='' && $field['name']=='password') continue;
  258. $service_settings[$service_id][$field['name']] = $_POST['qs_'.$service_id.'_'.$field['name']];
  259. }
  260. }
  261. }
  262. update_option('qs_service_settings', $service_settings);
  263. }
  264. }
  265. if(isset($_GET['qs_delete'])) {
  266. $_GET['qs_delete'] = intval($_GET['qs_delete']);
  267. $orders = get_option('qs_orders');
  268. if(is_array($orders)) {
  269. foreach($orders as $key => $order) {
  270. if($orders[$key]['order']['order_id'] == $_GET['qs_delete']) {
  271. unset($orders[$key]);
  272. update_option('qs_orders',$orders);
  273. }
  274. }
  275. }
  276. $message = __('Order deleted.','qtranslate');
  277. }
  278. if(isset($_GET['qs_cron'])) {
  279. qs_cron();
  280. $message = __('Status updated for all open orders.','qtranslate');
  281. }
  282. return $message;
  283. }
  284. function qs_translate_box($post) {
  285. global $q_config;
  286. $languages = qtrans_getSortedLanguages();
  287. ?>
  288. <ul>
  289. <?php
  290. $from = $q_config['default_language'];
  291. $to = '';
  292. foreach($languages as $language) {
  293. if($language!=$from) $to = $language;
  294. if(isset($_REQUEST['post'])) {
  295. ?>
  296. <li><img src="<?php echo trailingslashit(WP_CONTENT_URL).$q_config['flag_location'].$q_config['flag'][$language]; ?>" alt="<?php echo $q_config['language_name'][$language]; ?>"> <a href="edit.php?page=qtranslate_services&post=<?php echo intval($_REQUEST['post']); ?>&target_language=<?php echo $language; ?>"><?php echo $q_config['language_name'][$language]; ?> <span class="qsprice"></span></a></li>
  297. <?php
  298. } else {
  299. echo '<li>'.__('Please save your post first.','qtranslate').'</li>';
  300. break;
  301. }
  302. }
  303. ?>
  304. </ul>
  305. <script type="text/javascript">
  306. // <![CDATA[
  307. jQuery(document).ready(function() {
  308. jQuery.post(ajaxurl, {
  309. action: 'qs_quote',
  310. mode: 'price_only',
  311. translate_from: '<?php echo $from; ?>',
  312. translate_to: '<?php echo $to; ?>',
  313. service_id: 5,
  314. post_id: '<?php echo intval($_REQUEST['post']); ?>'},
  315. function(response) {
  316. eval(response);
  317. })
  318. });
  319. // ]]>
  320. </script>
  321. <?php
  322. }
  323. function qs_order_columns($columns) {
  324. return array(
  325. 'title' => __('Post Title', 'qtranslate'),
  326. 'service' => __('Service', 'qtranslate'),
  327. 'source_language' => __('Source Language', 'qtranslate'),
  328. 'target_language' => __('Target Language', 'qtranslate'),
  329. 'action' => __('Action', 'qtranslate')
  330. );
  331. }
  332. function qs_config_hook($request_uri) {
  333. global $q_config;
  334. ?>
  335. <h3><?php _e('qTranslate Services Settings', 'qtranslate') ?><span id="qtranslate-show-services" style="display:none"> (<a name="qtranslate_service_settings" href="#qtranslate_service_settings" onclick="showServices();"><?php _e('Show', 'qtranslate'); ?></a>)</span></h3>
  336. <table class="form-table" id="qtranslate-services">
  337. <tr>
  338. <th scope="row"><?php _e('qTranslate Services', 'qtranslate') ?></th>
  339. <td>
  340. <?php if(!qs_isOpenSSLAvailable()) { printf(__('<div id="message" class="error fade"><p>qTranslate Services could not load <a href="%s">OpenSSL</a>!</p></div>'), 'http://www.php.net/manual/book.openssl.php'); } ?>
  341. <label for="qtranslate_services"><input type="checkbox" name="qtranslate_services" id="qtranslate_services" value="1"<?php echo ($q_config['qtranslate_services'])?' checked="checked"':''; ?>/> <?php _e('Enable qTranslate Services', 'qtranslate'); ?></label>
  342. <br/>
  343. <?php _e('With qTranslate Services, you will be able to use professional human translation services with a few clicks.', 'qtranslate'); ?><br />
  344. </td>
  345. </tr>
  346. <?php
  347. if($q_config['qtranslate_services']) {
  348. $service_settings = get_option('qs_service_settings');
  349. $services = qs_queryQS(QS_GET_SERVICES);
  350. $orders = get_option('qs_orders');
  351. ?>
  352. <tr valign="top">
  353. <th scope="row"><h4><?php _e('Open Orders', 'qtranslate'); ?></h4></th>
  354. <td>
  355. <?php if(is_array($orders) && sizeof($orders)>0) { ?>
  356. <table class="widefat">
  357. <thead>
  358. <tr>
  359. <?php print_column_headers('order'); ?>
  360. </tr>
  361. </thead>
  362. <tfoot>
  363. <tr>
  364. <?php print_column_headers('order', false); ?>
  365. </tr>
  366. </tfoot>
  367. <?php
  368. foreach($orders as $order) {
  369. $post = &get_post($order['post_id']);
  370. if(!$post) continue;
  371. $post->post_title = esc_html(qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($post->post_title));
  372. ?>
  373. <tr>
  374. <td class="qs_no-bottom-border"><a href="post.php?action=edit&post=<?php echo $order['post_id']; ?>" title="<?php printf(__('Edit %s', 'qtranslate'),$post->post_title); ?>"><?php echo $post->post_title; ?></a></td>
  375. <td class="qs_no-bottom-border"><?php if(isset($services[$order['service_id']])): ?><a href="<?php echo $services[$order['service_id']]['service_url']; ?>" title="<?php _e('Website', 'qtranslate'); ?>"><?php echo $services[$order['service_id']]['service_name']; ?></a><?php endif; ?></td>
  376. <td class="qs_no-bottom-border"><?php echo $q_config['language_name'][$order['source_language']]; ?></td>
  377. <td class="qs_no-bottom-border"><?php echo $q_config['language_name'][$order['target_language']]; ?></td>
  378. <td class="qs_no-bottom-border"><a class="delete" href="<?php echo add_query_arg('qs_delete', $order['order']['order_id'], $request_uri); ?>#qtranslate_service_settings">Delete</a></td>
  379. </tr>
  380. <?php
  381. if(isset($order['status'])) {
  382. ?>
  383. <tr class="qs_status">
  384. <td colspan="5">
  385. <?php printf(__('Current Status: %s','qtranslate'), $order['status']); ?>
  386. </td>
  387. </tr>
  388. <?php
  389. }
  390. }
  391. ?>
  392. </table>
  393. <p><?php printf(__('qTranslate Services will automatically check every hour whether the translations are finished and update your posts accordingly. You can always <a href="%s">check manually</a>.','qtranslate'),'options-general.php?page=qtranslate&qs_cron=true#qtranslate_service_settings'); ?></p>
  394. <p><?php _e('Deleting an open order doesn\'t cancel it. You will have to logon to the service homepage and cancel it there.','qtranslate'); ?></p>
  395. <?php } else { ?>
  396. <p><?php _e('No open orders.','qtranslate'); ?></p>
  397. <?php } ?>
  398. </td>
  399. </tr>
  400. <tr valign="top">
  401. <th scope="row" colspan="2">
  402. <h4><?php _e('Service Configuration', 'qtranslate');?></h4>
  403. <p class="description"><!--<?php _e('Below, you will find configuration settings for qTranslate Service Providers, which are required for them to operate.', 'qtranslate'); ?>--></p>
  404. </th>
  405. </tr>
  406. <?php
  407. foreach($services as $service) {
  408. if(sizeof($service['service_required_fields'])>0) {
  409. ?>
  410. <tr valign="top">
  411. <th scope="row" colspan="2">
  412. <h5><?php _e($service['service_name']);?> ( <a name="qs_service_<?php echo $service['service_id']; ?>" href="<?php echo $service['service_url']; ?>"><?php _e('Website', 'qtranslate'); ?></a> )</h5>
  413. <p class="description"><?php _e($service['service_description']); ?></p>
  414. </th>
  415. </tr>
  416. <?php
  417. foreach($service['service_required_fields'] as $field) {
  418. ?>
  419. <tr valign="top">
  420. <th scope="row"><?php echo $field['title']; ?></th>
  421. <td>
  422. <input type="<?php echo ($field['name']=='password')?'password':'text';?>" name="<?php echo 'qs_'.$service['service_id']."_".$field['name']; ?>" value="<?php echo (isset($service_settings[$service['service_id']][$field['name']])&&$field['name']!='password')?$service_settings[$service['service_id']][$field['name']]:''; ?>" style="width:100%"/>
  423. </td>
  424. </tr>
  425. <?php
  426. }
  427. }
  428. }
  429. }
  430. ?>
  431. </table>
  432. <script type="text/javascript">
  433. // <![CDATA[
  434. function showServices() {
  435. document.getElementById('qtranslate-services').style.display='block';
  436. document.getElementById('qtranslate-show-services').style.display='none';
  437. return false;
  438. }
  439. if(location.hash!='#qtranslate_service_settings') {
  440. document.getElementById('qtranslate-show-services').style.display='inline';
  441. document.getElementById('qtranslate-services').style.display='none';
  442. }
  443. // ]]>
  444. </script>
  445. <?php
  446. }
  447. function qs_cron() {
  448. global $wpdb;
  449. // poll translations
  450. $orders = get_option('qs_orders');
  451. if(!is_array($orders)) return;
  452. foreach($orders as $key => $order) {
  453. qs_UpdateOrder($order['order']['order_id']);
  454. }
  455. }
  456. function qs_UpdateOrder($order_id) {
  457. global $wpdb;
  458. $orders = get_option('qs_orders');
  459. if(!is_array($orders)) return false;
  460. foreach($orders as $key => $order) {
  461. // search for wanted order
  462. if($order['order']['order_id']!=$order_id) continue;
  463. // query server for updates
  464. $order['order']['order_url'] = get_option('home');
  465. $result = qs_queryQS(QS_RETRIEVE_TRANSLATION, $order['order']);
  466. if(isset($result['order_comment'])) $orders[$key]['status'] = $result['order_comment'];
  467. // update db if post is updated
  468. if(isset($result['order_status']) && $result['order_status']==QS_STATE_CLOSED) {
  469. $order['post_id'] = intval($order['post_id']);
  470. $post = &get_post($order['post_id']);
  471. $title = qtrans_split($post->post_title);
  472. $content = qtrans_split($post->post_content);
  473. $title[$order['target_language']] = $result['order_translated_title'];
  474. $content[$order['target_language']] = $result['order_translated_text'];
  475. $post->post_title = qtrans_join($title);
  476. $post->post_content = qtrans_join($content);
  477. $wpdb->show_errors();
  478. $wpdb->query('UPDATE '.$wpdb->posts.' SET post_title="'.mysql_escape_string($post->post_title).'", post_content = "'.mysql_escape_string($post->post_content).'" WHERE ID = "'.$post->ID.'"');
  479. wp_cache_add($post->ID, $post, 'posts');
  480. unset($orders[$key]);
  481. }
  482. update_option('qs_orders',$orders);
  483. return true;
  484. }
  485. return false;
  486. }
  487. function qs_service() {
  488. global $q_config, $qs_public_key, $qs_error_messages;
  489. if(!isset($_REQUEST['post'])) {
  490. echo '<script type="text/javascript">document.location="edit.php";</script>';
  491. printf(__('To translate a post, please go to the <a href="%s">edit posts overview</a>.','qtranslate'), 'edit.php');
  492. exit();
  493. }
  494. $post_id = intval($_REQUEST['post']);
  495. $confirm = isset($_GET['confirm'])?true:false;
  496. $translate_from = '';
  497. $translate_to = '';
  498. $translate_from_name = '';
  499. $translate_to_name = '';
  500. if(isset($_REQUEST['source_language'])&&qtrans_isEnabled($_REQUEST['source_language']))
  501. $translate_from = $_REQUEST['source_language'];
  502. if(isset($_REQUEST['target_language'])&&qtrans_isEnabled($_REQUEST['target_language']))
  503. $translate_to = $_REQUEST['target_language'];
  504. if($translate_to == $translate_from) $translate_to = '';
  505. $post = &get_post($post_id);
  506. if(!$post) {
  507. printf(__('Post with id "%s" not found!','qtranslate'), $post_id);
  508. return;
  509. }
  510. $default_service = intval(get_option('qs_default_service'));
  511. $service_settings = get_option('qs_service_settings');
  512. // Detect available Languages and possible target languages
  513. $available_languages = qtrans_getAvailableLanguages($post->post_content);
  514. if(sizeof($available_languages)==0) {
  515. $error = __('The requested Post has no content, no Translation possible.', 'qtranslate');
  516. }
  517. // try to guess source and target language
  518. if(!in_array($translate_from, $available_languages)) $translate_from = '';
  519. $missing_languages = array_diff($q_config['enabled_languages'], $available_languages);
  520. if(empty($translate_from) && in_array($q_config['default_language'], $available_languages) && $translate_to!=$q_config['default_language']) $translate_from = $q_config['default_language'];
  521. if(empty($translate_to) && sizeof($missing_languages)==1) $translate_to = $missing_languages[0];
  522. if(in_array($translate_to, $available_languages)) {
  523. $message = __('The Post already has content for the selected target language. If a translation request is send, the current text for the target language will be overwritten.','qtranslate');
  524. }
  525. if(sizeof($available_languages)==1) {
  526. if($available_languages[0] == $translate_to) {
  527. unset($translate_to);
  528. }
  529. $translate_from = $available_languages[0];
  530. } elseif($translate_from == '' && sizeof($available_languages) > 1) {
  531. $languages = qtrans_getSortedLanguages();
  532. foreach($languages as $language) {
  533. if($language != $translate_to && in_array($language, $available_languages)) {
  534. $translate_from = $language;
  535. break;
  536. }
  537. }
  538. }
  539. // link to current page with get variables
  540. $url_link = add_query_arg('post', $post_id);
  541. if(!empty($translate_to)) $url_link = add_query_arg('target_language', $translate_to, $url_link);
  542. if(!empty($translate_from)) $url_link = add_query_arg('source_language', $translate_from, $url_link);
  543. // get correct title and content
  544. $post_title = qtrans_use($translate_from,$post->post_title);
  545. $post_content = qtrans_use($translate_from,$post->post_content);
  546. $post_excerpt = qtrans_use($translate_from,$post->post_excerpt);
  547. if(!empty($translate_from)) $translate_from_name = $q_config['language_name'][$translate_from];
  548. if(!empty($translate_to)) $translate_to_name = $q_config['language_name'][$translate_to];
  549. if(!empty($translate_from) && !empty($translate_to)) {
  550. $title = sprintf('Translate &quot;%1$s&quot; from %2$s to %3$s', htmlspecialchars($post_title), $translate_from_name, $translate_to_name);
  551. } elseif(!empty($translate_from)) {
  552. $title = sprintf('Translate &quot;%1$s&quot; from %2$s', htmlspecialchars($post_title), $translate_from_name);
  553. } else {
  554. $title = sprintf('Translate &quot;%1$s&quot;', htmlspecialchars($post_title));
  555. }
  556. // Check data
  557. if(isset($_POST['service_id'])) {
  558. $service_id = intval($_POST['service_id']);
  559. $default_service = $service_id;
  560. update_option('qs_default_service', $service_id);
  561. $order_key = substr(md5(time().AUTH_KEY),0,20);
  562. $request = array(
  563. 'order_service_id' => $service_id,
  564. 'order_url' => get_option('home'),
  565. 'order_key' => $order_key,
  566. 'order_title' => $post_title,
  567. 'order_text' => $post_content,
  568. 'order_excerpt' => $post_excerpt,
  569. 'order_source_language' => $translate_from,
  570. 'order_source_locale' => $q_config['locale'][$translate_from],
  571. 'order_target_language' => $translate_to,
  572. 'order_target_locale' => $q_config['locale'][$translate_to]
  573. );
  574. // check for additional fields
  575. if(isset($service_settings[$service_id]) && is_array($service_settings[$service_id])) {
  576. $request['order_required_field'] = array();
  577. foreach($service_settings[$service_id] as $setting => $value) {
  578. $request['order_required_field'][$setting] = $value;
  579. }
  580. }
  581. if(isset($_POST['token'])) $request['order_token'] = $_POST['token'];
  582. $answer = qs_queryQS(QS_INIT_TRANSLATION, $request);
  583. if(isset($answer['error'])) {
  584. $error = sprintf(__('An error occured: %s', 'qtranslate'), $qs_error_messages[$answer['error']]);
  585. if($answer['message']!='') {
  586. $error.='<br />'.sprintf(__('Additional information: %s', 'qtranslate'), qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($answer['message']));
  587. }
  588. }
  589. if(isset($answer['order_id'])) {
  590. $orders = get_option('qs_orders');
  591. if(!is_array($orders)) $orders = array();
  592. $orders[] = array('post_id'=>$post_id, 'service_id' => $service_id, 'source_language'=>$translate_from, 'target_language'=>$translate_to, 'order' => array('order_key' => $order_key, 'order_id' => $answer['order_id']));
  593. update_option('qs_orders', $orders);
  594. if(empty($answer['message'])) {
  595. $order_completed_message = '';
  596. } else {
  597. $order_completed_message = htmlspecialchars($answer['message']);
  598. }
  599. qs_UpdateOrder($answer['order_id']);
  600. }
  601. }
  602. if(isset($error)) {
  603. ?>
  604. <div class="wrap">
  605. <h2><?php _e('qTranslate Services', 'qtranslate'); ?></h2>
  606. <div id="message" class="error fade"><p><?php echo $error; ?></p></div>
  607. <p><?php printf(__('An serious error occured and qTranslate Services cannot proceed. For help, please visit the <a href="%s">Support Forum</a>','qtranslate'), 'http://www.qianqin.de/qtranslate/forum/');?></p>
  608. </div>
  609. <?php
  610. return;
  611. }
  612. if(isset($order_completed_message)) {
  613. ?>
  614. <div class="wrap">
  615. <h2><?php _e('qTranslate Services', 'qtranslate'); ?></h2>
  616. <div id="message" class="updated fade"><p><?php _e('Order successfully sent.', 'qtranslate'); ?></p></div>
  617. <p><?php _e('Your translation order has been successfully transfered to the selected service.','qtranslate'); ?></p>
  618. <?php
  619. if(!empty($order_completed_message)) {
  620. ?>
  621. <p><?php printf(__('The service returned this message: %s','qtranslate'), $order_completed_message);?></p>
  622. <?php
  623. }
  624. ?>
  625. <p><?php _e('Feel free to choose an action:', 'qtranslate'); ?></p>
  626. <ul>
  627. <li><a href="<?php echo add_query_arg('target_language', null, $url_link); ?>"><?php _e('Translate this post to another language.', 'qtranslate'); ?></a></li>
  628. <li><a href="edit.php"><?php _e('Translate a different post.', 'qtranslate'); ?></a></li>
  629. <li><a href="options-general.php?page=qtranslate#qtranslate_service_settings"><?php _e('View all open orders.', 'qtranslate'); ?></a></li>
  630. <li><a href="options-general.php?page=qtranslate&qs_cron=true#qtranslate_service_settings"><?php _e('Let qTranslate Services check if any open orders are finished.', 'qtranslate'); ?></a></li>
  631. <li><a href="<?php echo get_permalink($post_id); ?> "><?php _e('View this post.', 'qtranslate'); ?></a></li>
  632. </ul>
  633. </div>
  634. <?php
  635. return;
  636. }
  637. ?>
  638. <div class="wrap">
  639. <h2><?php _e('qTranslate Services', 'qtranslate'); ?></h2>
  640. <?php
  641. if(!empty($message)) {
  642. ?>
  643. <div id="message" class="updated fade"><p><?php echo $message; ?></p></div>
  644. <?php
  645. }
  646. ?>
  647. <h3><?php echo $title;?></h3>
  648. <form action="edit.php?page=qtranslate_services" method="post" id="qtranslate-services-translate">
  649. <p><?php
  650. if(sizeof($available_languages)>1) {
  651. $available_languages_name = array();
  652. foreach(array_diff($available_languages,array($translate_from)) as $language) {
  653. $available_languages_name[] = '<a href="'.add_query_arg('source_language',$language, $url_link).'">'.$q_config['language_name'][$language].'</a>';
  654. }
  655. $available_languages_names = join(", ", $available_languages_name);
  656. printf(__('Your article is available in multiple languages. If you do not want to translate from %1$s, you can switch to one of the following languages: %2$s', 'qtranslate'),$q_config['language_name'][$translate_from],$available_languages_names);
  657. }
  658. ?></p>
  659. <input type="hidden" name="post" value="<?php echo $post_id; ?>"/>
  660. <input type="hidden" name="source_language" value="<?php echo $translate_from; ?>"/>
  661. <?php
  662. if(empty($translate_to)) {
  663. ?>
  664. <p><?php _e('Please choose the language you want to translate to:', 'qtranslate');?></p>
  665. <ul>
  666. <?php
  667. foreach($q_config['enabled_languages'] as $language) {
  668. if($translate_from == $language) continue;
  669. ?>
  670. <li><label><input type="radio" name="target_language" value="<?php echo $language;?>" /> <?php echo $q_config['language_name'][$language]; ?></li>
  671. <?php
  672. }
  673. ?>
  674. </ul>
  675. <p class="submit">
  676. <input type="submit" name="submit" class="button-primary" value="<?php _e('Continue', 'qtranslate') ?>" />
  677. </p>
  678. <?php
  679. } else {
  680. ?>
  681. <input type="hidden" name="target_language" value="<?php echo $translate_to; ?>"/>
  682. <?php if($confirm): ?>
  683. <input type="hidden" name="service_id" value="<?php echo $_REQUEST['service_id']; ?>"/>
  684. <input type="hidden" name="token" value="<?php echo $_REQUEST['token']; ?>"/>
  685. <div id="submitboxcontainer" class="metabox-holder">
  686. <div id="submitdiv" class="postbox">
  687. <h3 class="hndle"><?php _e('Confirm Order', 'qtranslate'); ?></h3>
  688. <div class="inside">
  689. <p><?php _e('Please confirm your order.', 'qtranslate'); ?></p>
  690. <div class="qs_submit"><a class="button-primary" onclick="sendorder();"><?php _e('Confirm Order', 'qtranslate'); ?></a></div>
  691. </div>
  692. </div>
  693. </div>
  694. <?php else: ?>
  695. <div id="submitboxcontainer" class="metabox-holder">
  696. <div id="submitdiv" class="postbox">
  697. <h3 class="hndle"><?php _e('Request Translation', 'qtranslate'); ?></h3>
  698. <div class="inside request">
  699. <noscript><?php _e('Javascript is required for qTranslate Services', 'qtranslate'); ?></noscript>
  700. <p><?php _e('Please choose a service first', 'qtranslate'); ?></p>
  701. </div>
  702. </div>
  703. </div>
  704. <?php endif; ?>
  705. <?php
  706. $timestamp = time();
  707. if($timestamp != qs_queryQS(QS_VERIFY, $timestamp)) {
  708. ?>
  709. <p class="error"><?php _e('ERROR: Could not connect to qTranslate Services. Please try again later.', 'qtranslate');?></p>
  710. <?php
  711. return;
  712. }
  713. ?>
  714. <div id="qs_boxes" class="metabox-holder">
  715. <div class="postbox">
  716. <h3 class="hndle"><?php _e('Translation Service', 'qtranslate'); ?></h3>
  717. <div class="inside">
  718. <ul>
  719. <?php
  720. if($services = qs_queryQS(QS_GET_SERVICES)) {
  721. foreach($services as $service_id => $service) {
  722. // check if we have data for all required fields
  723. $requirements_matched = true;
  724. foreach($service['service_required_fields'] as $field) {
  725. if(!isset($service_settings[$service_id][$field['name']]) || $service_settings[$service_id][$field['name']] == '') $requirements_matched = false;
  726. }
  727. if(!$requirements_matched) {
  728. ?>
  729. <li>
  730. <label><input type="radio" name="service_id" disabled="disabled" /> <b><?php echo qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($service['service_name']); ?></b> ( <a href="<?php echo $service['service_url']; ?>" target="_blank"><?php _e('Website', 'qtranslate'); ?></a> )</label>
  731. <p class="error"><?php printf(__('Cannot use this service, not all <a href="%s">required fields</a> filled in for this service.','qtranslate'), 'options-general.php?page=qtranslate#qs_service_'.$service_id); ?></p>
  732. <p class="service_description"><?php echo qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($service['service_description']); ?></p>
  733. </li>
  734. <?php
  735. } else {
  736. ?>
  737. <li><label><input type="radio" id="qs_service_<?php echo $service['service_id'];?>" onclick="chooseservice(this.value)" value="<?php echo $service['service_id'];?>" <?php echo $confirm?'disabled="disabled"':'name="service_id"'; ?> /> <b><?php echo qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($service['service_name']); ?></b> ( <a href="<?php echo $service['service_url']; ?>" target="_blank"><?php _e('Website', 'qtranslate'); ?></a> )</label><p class="service_description"><?php echo qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($service['service_description']); ?></p></li>
  738. <?php
  739. }
  740. }
  741. ?>
  742. </ul>
  743. <script type="text/javascript">
  744. function chooseservice(id) {
  745. jQuery('#qs_service_'+id).attr('checked','checked');
  746. jQuery('#submitdiv .request').html('<?php _e('<p><img src="images/wpspin_light.gif"> Getting Quote...</p>', 'qtranslate'); ?>');
  747. jQuery.post(ajaxurl, {
  748. action: 'qs_quote',
  749. translate_from: '<?php echo $translate_from; ?>',
  750. translate_to: '<?php echo $translate_to; ?>',
  751. service_id: id,
  752. post_id: '<?php echo $post_id; ?>'},
  753. function(response) {
  754. eval(response);
  755. });
  756. }
  757. function sendorder() {
  758. jQuery("#qtranslate-services-translate").submit();
  759. }
  760. chooseservice('<?php echo isset($_REQUEST['service_id'])?$_REQUEST['service_id']:$default_service; ?>');
  761. </script>
  762. </div>
  763. </div>
  764. <div class="postbox closed">
  765. <div class="handlediv" title="<?php _e('Click to toggle'); ?>" onclick="jQuery(this).parent().removeClass('closed');jQuery(this).hide();"><br></div>
  766. <h3 class="hndle"><?php _e('Review Article', 'qtranslate'); ?></h3>
  767. <div class="inside">
  768. <textarea name="qs_content_preview" id="qs_content_preview" readonly="readonly"><?php echo $post_content; ?></textarea>
  769. </div>
  770. </div>
  771. <p><?php _e('Your article will be SSL encrypted and securly sent to qTranslate Services, which will forward your text to the chosen Translation Service. Once qTranslate Services receives the translated text, it will automatically appear on your blog.', 'qtranslate'); ?></p>
  772. <?php
  773. }
  774. ?>
  775. </div>
  776. <?php
  777. }
  778. ?>
  779. </div>
  780. </form>
  781. <?php
  782. }
  783. function qs_quote() {
  784. global $q_config;
  785. $mode = 'full';
  786. if(isset($_POST['mode'])) $mode = $_POST['mode'];
  787. if($mode!='price_only') $mode = 'full';
  788. $service_id = $_POST['service_id'];
  789. $translate_from = $_POST['translate_from'];
  790. $translate_to = $_POST['translate_to'];
  791. $post = &get_post($_POST['post_id']);
  792. $post = qtrans_use($translate_from, $post);
  793. $post_title = $post->post_title;
  794. $post_content = $post->post_content;
  795. $post_excerpt = $post->post_excerpt;
  796. $request = array(
  797. 'order_service_id' => $service_id,
  798. 'order_title' => $post_title,
  799. 'order_text' => $post_content,
  800. 'order_excerpt' => $post_excerpt,
  801. 'order_source_language' => $translate_from,
  802. 'order_source_locale' => $q_config['locale'][$translate_from],
  803. 'order_target_language' => $translate_to,
  804. 'order_target_locale' => $q_config['locale'][$translate_to],
  805. 'order_confirm_url' => get_admin_url(null, 'edit.php?page=qtranslate_services&confirm=1&post='.$_POST['post_id'].'&source_language='.$translate_from.'&target_language='.$translate_to.'&service_id='.$service_id),
  806. 'order_failure_url' => get_admin_url(null, 'edit.php?page=qtranslate_services&post='.$_POST['post_id'].'&source_language='.$translate_from.'&target_language='.$translate_to.'&service_id='.$service_id)
  807. );
  808. $answer = qs_queryQS(QS_QUOTE, $request);
  809. $price = __('unavailable', 'qtranslate');
  810. $currency = '';
  811. $short = '';
  812. if(isset($answer['price'])) {
  813. if($answer['price'] == 0) {
  814. $price = __('free', 'qtranslate');
  815. } else if($answer['price'] < 0) {
  816. $price = __('unavailable', 'qtranslate');
  817. } else {
  818. $price = number_format_i18n($answer['price'],2);
  819. $currency = $answer['currency'];
  820. }
  821. $content = sprintf(__('<p>Price: %1$s %2$s</p>','qtranslate'), $currency, $price);
  822. $short = sprintf(__('~ %1$s %2$s','qtranslate'), $currency, $price);
  823. if(!empty($answer['paypalurl'])) {
  824. $content .= '<div class="qs_submit"><a href="'.$answer['paypalurl'].'"><img src="https://fpdbs.paypal.com/dynamicimageweb?cmd=_dynamic-image&locale='.$q_config['locale'][$q_config['language']].'"></a></div>';
  825. } else {
  826. $content .= '<div class="qs_submit"><a class="button-primary" onclick="sendorder();">'.__('Request Translation', 'qtranslate').'</a></div>';
  827. }
  828. } else {
  829. $content = '<p>'.__('An error occured!', 'qtranslate');
  830. if(isset($answer['error'])) $content .= '<br>'.$answer['message'];
  831. $content .= '</p>';
  832. }
  833. if($mode == 'full') {
  834. echo "jQuery('#submitdiv .request').html('";
  835. echo $content;
  836. echo "');";
  837. } else if($mode == 'price_only') {
  838. echo "jQuery('.qsprice').html('";
  839. echo $short;
  840. echo "');";
  841. }
  842. die();
  843. }
  844. function qs_toobar($content) {
  845. // Create Translate Button
  846. $content .= qtrans_createEditorToolbarButton('translate', 'translate', 'init_qs', __('Translate'));
  847. return $content;
  848. }
  849. function qs_editor_js($content) {
  850. $content .= "
  851. init_qs = function(action, id) {
  852. document.location.href = 'edit.php?page=qtranslate_services&post=".intval($_REQUEST['post'])."';
  853. }
  854. ";
  855. return $content;
  856. }
  857. ?>