function translateOneNode($currentNodeID, $to_languages, $content_type) { global $db, $XMLarray, $error_log; $separator = "7543545165934149"; // Fetch a node from Drupal if a copy does not already exist in sources dir. // $xml_MASTER is the original English-language version // $xml is the copy that will be translated $fn = getcwd() . "/sources/SOURCE_" . $currentNodeID . ".XML"; if (file_exists($fn)) { $xml_MASTER = file_get_contents($fn); if ($content_type == "page") { // Remove <teaser> from "page". The "teaser" is created by truncating the <body>, resulting in invalid XML $xml_MASTER = preg_replace("|<teaser>.*?</teaser>|us", "<teaser></teaser>", $xml_MASTER); } } else { $xml_MASTER = fetchOneNode($currentNodeID); if ($content_type == "page") { $xml_MASTER = preg_replace("|<teaser>.*?</teaser>|us", "<teaser></teaser>", $xml_MASTER); } $fh = fopen($fn, "w"); fwrite($fh, $xml_MASTER); fclose($fh); } foreach ($to_languages as $to_language) { $query = "select drupal_code from sovee.languages where sovee_code = '" . $to_language . "'"; $result = mysql_query($query, $db); while ($row = mysql_fetch_assoc($result)) { $drupalLanguageCode = $row['drupal_code']; } mysql_free_result($result); echo "\n=====================================================================================\n========== ==========\n. . . Translating node {$currentNodeID} ({$content_type}) into {$to_language} . . . \n"; $error_IncompleteNodeFlag = 0; $xml = $xml_MASTER; // Create a copy of the master, to be translated // Convert XML to array $XMLarray = XML2Array::createArray($xml); // Get info about the node // Requested info is placed in the $requestedTags array // and returned in the assoc. array info() $requestedTags = array("type", "tnid"); $info = getXMLinfo($xml, $requestedTags); $derivedContentType = $info['type']; // Build list of containers to parse for the given content_type. $query = "select DISTINCT sovee.node_fields.name from sovee.content_type \nLEFT JOIN sovee.field_map ON sovee.content_type.id = sovee.field_map.content_id\nLEFT JOIN sovee.node_fields ON sovee.node_fields.id = sovee.field_map.field_id\nWHERE sovee.content_type.name = '" . $derivedContentType . "'"; $result = mysql_query($query, $db); while ($row = mysql_fetch_assoc($result)) { $containerArrayTemplate[] = $row['name']; } mysql_free_result($result); // Walk throught the array, extract the specified containers, translate // and replace in the array // All array elements are assumed to be in the [node_export][node] array // $containerArrayTemplate = array("body", "title", "teaser", "field_product_subtitle|n*|value", "field_warranty|n*|value", "field_product_education|n*|value", // "field_prod_man_docs_link|n*|title", // "field_did_you_know|n*|value", "field_product_benefits|n*|value", "nodewords|copyright|value", "nodewords|dcterms.contributor|value", // "nodewords|dcterms.title|value", "nodewords|description|value", "nodewords|keywords|value" ); $containerArray = expandTemplate($containerArrayTemplate); $allContainers = "<div>{$separator}"; foreach ($containerArray as $oneContainer) { echo "\nProcessing container {$oneContainer}\n"; $parents = explode("|", $oneContainer); array_unshift($parents, "node_export", "node"); #echo "Parents: "; #print_r($parents); $XMLfragment = drupal_array_get_nested_value($XMLarray, $parents); if (is_array($XMLfragment)) { $XMLfragment = ""; } $translatedFragment = ""; $patterns = array("|^<div>|us", "|</div>\$|us"); // The "|u" flag enables multibyte support $replacements = array("", ""); if (strlen(trim($XMLfragment)) > 0 and !is_array($XMLfragment)) { $XMLfragment = "<div>" . $XMLfragment . "</div>"; // Encapsulate in dummy <div> to satisfy Sovee translator // echo "ORIGINAL Fragment = |$XMLfragment|\n"; } else { echo "Original Fragment |{$XMLfragment}| is empty -- skipping.\n"; } $allContainers .= $XMLfragment . $separator; // Add at the end of each container to faciliate preg_split } // ------- End of foreach($containerArray as $oneContainer) $allContainers .= "</div>"; // Translate the entire node if target language is not English echo "TO_LANGUAGE = {$to_language}\n"; $xxx = substr($to_language, 0, 2); echo "SUBSTR = |{$xxx}|\n"; $sovee_to_language = $to_language; if (substr($to_language, 0, 2) != "en") { if ($to_language == "es-419") { $sovee_to_language = "es-es"; } // Use standard Spanish for Latin America echo "Sending strings to Sovee . . . \n"; $translatedFragmentAry = translateFrag($allContainers, $currentNodeID, "FULL NODE", $to_language); // Perform the translation $translatedFragment = $translatedFragmentAry['content']; $translatedFragmentError = $translatedFragmentAry['error_count']; // Count of translation errors. 0 = success $error_IncompleteNodeFlag += $translatedFragmentError; } else { echo "English-to-English: No translation needed.\n"; $translatedFragment = $allContainers; $translatedFragmentError = 0; } // print_r($translatedFragmentAry); $separatorPattern = "/{$separator}/u"; $translatedNodeAry = preg_split($separatorPattern, $translatedFragment); // print_r($translatedNodeAry); $translatedContentPointer = 1; reset($containerArray); foreach ($containerArray as $oneContainer) { $parents = explode("|", $oneContainer); array_unshift($parents, "node_export", "node"); $stripped = trim(preg_replace($patterns, $replacements, $translatedNodeAry[$translatedContentPointer])); // Remove the leading and trailing <div>s from the node fragments // Special handling for page_title, which can be a string or an array if ($oneContainer == "page_title" and $stripped == "Array") { $pageTitleParents1 = array('node_export', 'node', 'page_title', 'value'); $pageTitleParents2 = array('node_export', 'node', 'page_title', 'attributes', 'type'); drupal_array_set_nested_value($XMLarray, $pageTitleParents1, "FALSE"); drupal_array_set_nested_value($XMLarray, $pageTitleParents2, "boolean"); } else { if (strlen($stripped) > 0) { drupal_array_set_nested_value($XMLarray, $parents, $stripped); } } $translatedContentPointer++; } // HTML-Encode any info in the <data> container // $dataParents = array('node_export', 'node', 'data'); // $dataFragment = htmlentities(drupal_array_get_nested_value($XMLarray, $dataParents)); // drupal_array_set_nested_value($XMLarray, $dataParents, $dataFragment); #echo "TRANSLATED XML ARRAY:"; #print_r($XMLarray); // Does an older version of this translated node exist? // If yes, return the node# and alias in an array // otherwise, $oldNodeID_ary['number'] == '' $oldNodeID_ary = findOldTranslation($currentNodeID, $to_language); $oldNodeID = $oldNodeID_ary['number']; $oldNodeIDalias = $oldNodeID_ary['url_alias']; if ($oldNodeID != "") { echo "\nFound old node number -- old={$oldNodeID}\n"; } if ($oldNodeIDalias != "") { echo "\nFound old node number alias -- old={$oldNodeIDalias}\n"; } // Update the nid and tnid fields // For new nodes, nid='' // and tnid = the current nid value $XMLarray['node_export']['node']['tnid'] = $currentNodeID; $XMLarray['node_export']['node']['nid'] = $oldNodeID; // $XMLarray['node_export']['node']['language'] = $oldNodeID['drupal_lang_code']; $XMLarray['node_export']['node']['language'] = $drupalLanguageCode; // // // $XMLarray['node_export']['node']['path'] = $oldNodeID['url_alias']; if (isset($XMLarray['node_export']['node']['xmlsitemap']['language'])) { // $XMLarray['node_export']['node']['xmlsitemap']['language'] = $oldNodeID['drupal_lang_code']; $XMLarray['node_export']['node']['xmlsitemap']['language'] = $drupalLanguageCode; } //echo "XMLARRAY = \n"; //print_r($XMLarray); $FOO = $XMLarray['node_export']['node']['nodewords']['location']['latitude']; $BAR = $XMLarray['node_export']['node']['nodewords']['location']['longitude']; echo "FOO = {$FOO}\nBAR = {$BAR}\n"; // If lat or long > 8 chars, set to zero, otherwise node will not import if (isset($XMLarray['node_export']['node']['nodewords']['location']['latitude'])) { if (strlen($XMLarray['node_export']['node']['nodewords']['location']['latitude']) > 8) { $XMLarray['node_export']['node']['nodewords']['location']['latitude'] = 0; } } if (isset($XMLarray['node_export']['node']['nodewords']['location']['longitude'])) { if (strlen($XMLarray['node_export']['node']['nodewords']['location']['longitude']) > 8) { $XMLarray['node_export']['node']['nodewords']['location']['longitude'] = 0; } } // Adjust the menu references $this_plid = $XMLarray['node_export']['node']['menu']['plid']; $this_menu_name = $XMLarray['node_export']['node']['menu']['menu_name']; if ($this_menu_name == "primary-links") { $mquery = "SELECT t_menuid from sovee.menus LEFT JOIN sovee.languages on sovee.menus.language_code = sovee.languages.id WHERE drupal_code = \"" . $drupalLanguageCode . "\" and Eng_menuid = \"" . $this_plid . "\""; echo "MQ = {$mquery}\n"; $rmquery = mysql_query($mquery, $db); $err_msg = trim(mysql_error($db)); if (strlen($err_msg) > 0) { echo "{$mquery}\n{$err_msg}\n\n\n"; } while ($m1 = mysql_fetch_assoc($rmquery)) { $newPlid = $m1['t_menuid']; $XMLarray['node_export']['node']['menu']['plid'] = $newPlid; } mysql_free_result($rmquery); } // Convert array back to XML $encoding = "UTF-8"; $xmlVersion = "1.0"; Array2XML::init($xmlVersion, $encoding); $xmlobj = Array2XML::createXML('DELETE_ME', $XMLarray); // Convert a PHP array to XML, using 'DELETE_ME' as the root_node_name $translated_xml = $xmlobj->saveXML(); // Returned object is of type DOMDocument $translated_xml = preg_replace("/<[\\/]?DELETE_ME>[\n]/u", "", $translated_xml); $fn = getcwd() . "/TRANSLATED_" . $drupalLanguageCode . "_" . $currentNodeID . ".XML"; echo "WRITING {$fn}\n"; $fh = fopen($fn, "w"); fwrite($fh, $translated_xml); fclose($fh); // If node translation was successful, // import the translated node back into Drupal if ($error_IncompleteNodeFlag == 0) { $cmd = "/usr/bin/drush --root=/var/www/pressflow node-export-import --file={$fn}"; echo "COMMAND = {$cmd}\n"; $success = `{$cmd}`; $error = "DRUSH IMPORT RESULTS: {$success}\n"; echo $error; fwrite($error_log, $error); $cmd = "/bin/rm {$fn}"; #$success = `$cmd`; $q1 = "INSERT INTO sovee.progress (node, status, type, language) VALUES(\"" . $currentNodeID . "\", \"1\", \"" . $derivedContentType . "\", \"" . $to_language . "\") ON DUPLICATE KEY UPDATE status=VALUES(status)"; echo "Q1={$q1}\n"; $r1 = mysql_query($q1, $db); } else { $error = "Node {$currentNodeID} ({$content_type}) not completely translated. Not importing into Drupal.\n"; echo $error; $q1 = "INSERT INTO sovee.progress (node, status, type, language) VALUES(\"" . $currentNodeID . "\", \"0\", \"" . $derivedContentType . "\", \"" . $to_language . "\") ON DUPLICATE KEY UPDATE status=VALUES(status)"; $r1 = mysql_query($q1, $db); $err_msg = trim(mysql_error($db)); if (strlen($err_msg) > 0) { echo "{$q1}\n{$err_msg}\n\n\n"; } fwrite($error_log, $error); } echo "========== ==========\n=====================================================================================\n"; } $translated_xml_array = array('status' => $error_IncompleteNodeFlag, 'translated_xml' => $translated_xml); return $translated_xml_array; }
#!/usr/bin/php <?php $to_language = "es-es"; // This one fails $fragment = '<p>We are so confident in our products that we are the only ultrasound company to offer a <strong><a href="/support/warranty-and-service">five-year standard warranty</a></strong>.</p>'; // This one succeeds. Uncomment to test // $fragment='<p><strong><a href="/support/warranty-and-service">five-year standard warranty</a></strong>.</p>'; $token = getSoveeAuthToken(); $translation = translateFrag($fragment, $to_language, $token); echo "Translation is {$translation}\n\n"; // ============================================================= // // Pass HTML fragment to Sovee API (v3), return translation // Use GET request, passing lang. abbrevs and authentication info ($data) // in the query string // Pass the HTML fragment ($content) in the body function translateFrag($fragment, $languageAbbrev, $token) { $data = array('from' => 'en-us', 'to' => $languageAbbrev, 'customer' => 'SonoSite', 'token' => $token, 'project' => 'www.sonosite.com'); $contentAry = array('html' => $fragment); print_r($contentAry); $content = http_build_query($contentAry, 'PHP_QUERY_RFC3986'); $query_string = http_build_query($data, 'PHP_QUERY_RFC3986'); $url = "https://translate.sovee.com/html-fragment?" . $query_string; echo "URL={$url}\n\n"; echo "Content = {$content}\n\n"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, FALSE); curl_setopt($ch, CURLOPT_HTTPGET, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
#!/usr/bin/php <?php Mb_Internal_Encoding('UTF-8'); $loc = "UTF-8"; putenv("LANG={$loc}"); $loc = setlocale(LC_ALL, $loc); $token = getSoveeAuthToken(); $stringTest = translateString("en-us", "it-it", "This is my string"); echo "Stringtest = |{$stringTest}|\n"; $fragment = "<div>this is a test</div>"; $fragmentTest = translateFrag($fragment, 0, "foo", "it-it"); print_r($fragmentTest); # =================================================================== function getSoveeAuthToken() { $data = array('username' => '*****@*****.**', 'password' => 'bill3cat', 'customer' => 'SonoSite'); $ch = curl_init(); $url = "https://auth.sovee.com/auth/login.txt"; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_BINARYTRANSFER, TRUE); curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE); curl_setopt($ch, CURLOPT_FORBID_REUSE, TRUE); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_PROXY, "itproxy.sonosite.com"); curl_setopt($ch, CURLOPT_PROXYPORT, "3128"); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ch, CURLOPT_COOKIEJAR, "/home/cjacks/translate/cookies"); curl_setopt($ch, CURLOPT_COOKIEFILE, "/home/cjacks/translate/cookies");
// if string contains <span class='dont_translate'>.*?</span> then restore < and > $EnglishBatchAry[$m1['lid']] = $sourceString; $unTranslatedAry[$m1['lid']] = $m1['source']; echo "unTranslatedAry[" . $m1['lid'] . "] = " . $m1['source'] . "\n"; $batch .= "<div name=\"" . $separator . "\" id=\"" . $m1['lid'] . "\">" . $sourceString . "</div>\n"; } mysql_free_result($r1); $batch .= "</div>"; $lengthOfBatchString = strlen($batch); $msg = "batch = |{$batch}|\nLength={$lengthOfBatchString}\n\n"; echo $msg; fwrite($error_log, $msg); // Send the batch, enclosed in <div>s, to translation if ($lengthOfBatchString > 11) { // Empty $batch = <div></div> , which is 11 chars $rawTranslatedArray = translateFrag($batch, 0, "STRING", $sovee_code); // Perform the translation $translatedArray = makeIndexedArray($rawTranslatedArray['content'], $separator); echo "=====================\n"; echo "unTranslatedAry:\n"; print_r($unTranslatedAry); echo "translatedArray:\n"; print_r($translatedArray); // Inner loop #1. Get default values for any translation of these strings foreach ($translatedArray as $lidValue => $translatedText) { $q2 = "SELECT distinct plid, plural,i18n_status,l10n_status from locales_target where lid=\"{$lidValue}\""; $r2 = mysql_query($q2, $db); $numReturned = mysql_num_rows($r2) + 0; $plid = $plural = $i18n_status = $l10n_status = 0; if ($numReturned != 1) { $msg = "Query returned {$numReturned} rows for lid={$lidValue}\n {$q2}\n";
<?php ini_set("auto_detect_line_endings", true); $languages = array("German" => "de", "Spanish" => "es", "Italian" => "it", "Russian" => "ru", "Japanese" => "ja", "Korean" => "ko", "French" => "fr", "Portuguese" => "pt"); ksort($languages); $dbserver = "localhost"; $dbuser = "******"; $dbpass = "******"; $dbname = "sonosite"; $db = mysql_connect($dbserver, $dbuser, $dbpass); if (!$db) { die('Could not connect: ' . mysql_error()); } mysql_select_db($dbname, $db); $XMLfragment = fetchOneNode(259); echo $XMLfragment; $trans = translateFrag($XMLfragment, "fr"); echo "\n\n\n\n\n\n\n{$trans}\n"; # ============================================================= # # Fetch node numbers of all English or Language-Neutral nodes # Return array of node numbers function fetchEnglishNodes() { global $db; $query = "SELECT nid from node where\n (language='en-us' OR language='')\n\t\tAND status=1\n\t\tORDER BY nid"; $result = mysql_query($query, $db); while ($row = $myrow = mysql_fetch_assoc($result)) { $nodeAry[] = $row['nid']; } return $nodeAry; }