'admin/settings/gtrans', 'title' => t('Google Translation'), 'description' => t('Control Google Translate service.'), 'callback' => 'drupal_get_form', 'callback arguments' => 'gtrans_settings'); return $items; } /** * Settings form. */ function gtrans_settings(){ $languages = gtrans_get_avail_langs(); $form['gtrans_enabled_languages']=array('#type'=>'checkboxes', '#title'=>t('Enabled languages'), '#options' => $languages, '#default_value' => variable_get('gtrans_enabled_languages', array('en', 'fr', 'de')), ); $form['gtrans_your_language']=array('#type'=>'radios', '#title'=>t('Site language'), '#options' => $languages, '#default_value' => variable_get('gtrans_your_language', 'en'), ); return system_settings_form($form); } /** * Implementation of hook_block(). */ function gtrans_block($op = 'list', $delta = 0, $edit = array()) { if ($op == 'list') { $blocks[0]['info'] = t('Change Language'); return $blocks; } elseif ($op == 'view') { $block = array(); switch ($delta) { case 0: $block['subject'] = t('Change Language'); $block['content'] = drupal_get_form('gtrans_change_language_form'); return $block; } } } function gtrans_change_language_form(){ $languages = gtrans_get_avail_langs(); // get enabled languages, assume french and spanish by default $lang = variable_get('gtrans_enabled_languages', array('fr' => 'fr', 'es' => 'es')); $hls = array(); // show only enabled language foreach($lang as $key => $val){ if(!is_null($languages[$val])){ $hls[$val] = $languages[$val]; } } $form['hl'] = array('#type' => 'select', '#default_value' => ($_SESSION['hl']? $_SESSION['hl'] : 'fr'), '#options' =>$hls, '#prefix' => '
', ); $form['submit'] = array('#type' => 'submit', '#value' => t('Change'), '#suffix' => '
', ); return $form; } /** * Implementation of hook_submit(). */ function gtrans_change_language_form_submit($form_id, $edit){ $_SESSION['drupal_hl'] = $edit['hl']; } /** * Implementation of hook_init(). */ function gtrans_init(){ /* avoid calling translation for POSTed pages and for pages called by Google Translate service, otherwise we'll end up going in a chain of calls of the current drupal page */ if(!$_GET['gtrans'] && !$_POST && _garg(0)!='admin'){ if($_SESSION['drupal_hl']){ gtrans_translate_page($_SESSION['drupal_hl']); } } } /** * Connect to google translate and send headers. Collect result and return */ function gtrans_google_connection($url,$uri,$redirect_max,$redirect_count=0) { // initialize return content to "" $content = ""; // open socket $fp=fsockopen($url, 80, $errno, $errstr, 60); if(!$fp){ watchdog('user', t('Attempt failed to translate page').' '.$_SERVER['REQUEST_URI'].' '.t('to').' '.$languages[$hl].': Couldn\'t contact Google Translate server'); break; } else{ // connected! // prepare headers to send $out = "GET /".$uri." HTTP/1.1\r\n"; $out .= "Host: ".$url."\r\n"; $out .= "Connection: Close\r\n\r\n"; // send header fwrite($fp, $out); // receive data $body = false; while (!feof($fp)) { $s = fgets($fp, 1024); if ((stristr($s,"HTTP/1.1 301")!="") || (stristr($s,"HTTP/1.1 302")!="")) { // if a 301 or 302 is provided by google translate, parse the next line for the redirection URL $s = fgets($fp,1024); $redirect=preg_replace("/location:/i","",$s); $url_bits = parse_url(trim($redirect)); if($redirect_count < $redirect_max) { // we are under the redirect limit, call self on new url.. fclose($fp); return gtrans_google_connection($url_bits['host'],$uri,$redirect_max,$redirect_count+1); } else { // over the redirect limit, return what we've got fclose($fp); return $content; } } if ( $body ) $content .= $s; // ignore HTTP headers if ( $s == "\r\n" ) $body = true; } // close the connection fclose($fp); // check the data we got: if(!strlen($content)){ watchdog('user', t('Attempt failed to translate page').' '.$_SERVER['REQUEST_URI'].' '.t('to').' '.$languages[$hl].': No content from Google Translate server'); } } return $content; } /** * The real stuf: translate the whole drupal page and send it to the browser. */ function gtrans_translate_page($hl='fr'){ $languages = gtrans_get_avail_langs(); // make sure we're not translating from and to the // same language if($hl != variable_get('gtrans_your_language', 'en')){ global $base_url; // Google Translate IP $url = 'translate.google.com'; // prepare the request, add a parameter to prevent // recursively attempting to translate $req_uri = str_replace('destination=', '', drupal_get_destination()); $uri = 'translate_c?hl=en&ie=UTF-8&oe=UTF-8&langpair='.variable_get('gtrans_your_language', 'en').'%7C'.$hl.'&u='.$base_url.'/'.$req_uri.'%3Fgtrans%3Dtrue'; // send url and uri to google - follow up to 3 redirects $content = gtrans_google_connection($url,$uri,3); // check the data we got: if(!strlen($content)){ watchdog('user', t('Attempt failed to translate page').' '.$_SERVER['REQUEST_URI'].' '.t('to').' '.$languages[$hl].': No content from Google Translate server'); } else{ // now prepare content $content_array = explode("\r\n", $content); $content = $content_array[1]; // Google Translate modifes all links to point to it, // we will reverse this action and take the links back $content = preg_replace('//', '', $content); // now translate HTML entites $content = str_replace(str_replace('%7C', '%7C', htmlentities($uri)), '', $content); // set language in session $_SESSION['drupal_hl'] = $hl; // shoot the translated page and end script run if(strlen($content)>30){ die($content); } else{ watchdog('user', t('Attempt failed to translate page').' '.$_SERVER['REQUEST_URI'].' '.t('to').' '.$languages[$hl].': Content I got was: '.$content); } } } } /** * A duplicate of arg() * */ function _garg($index) { static $arguments, $q; if (empty($arguments) || $q != $_GET['q']) { $arguments = explode('/', $_GET['q']); $q = $_GET['q']; } if (isset($arguments[$index])) { return $arguments[$index]; } } function gtrans_get_avail_langs(){ return array( 'ar'=> 'Arabic', 'en'=> 'English', 'fr'=> 'French', 'de'=> 'Deutsch', 'it'=> 'Italian', 'es'=> 'Spanish', 'pt'=> 'Portuguese', 'ja'=> 'Japanese', 'zh-CN'=> 'Chinese', 'ko'=> 'Korean', ); } ?>