Index: admin_templates/languages/phrase_edit.tpl
===================================================================
--- admin_templates/languages/phrase_edit.tpl (revision 14184)
+++ admin_templates/languages/phrase_edit.tpl (working copy)
@@ -81,8 +81,53 @@
<inp2:m_RenderElement name="inp_label" prefix="phrases" field="PrimaryTranslation" title="la_fld_PrimaryTranslation"/>
<inp2:m_RenderElement name="inp_edit_box" prefix="phrases" field="Phrase" title="la_fld_Phrase" size="60"/>
- <inp2:m_RenderElement name="inp_edit_textarea_ml" prefix="phrases" field="Translation" title="la_fld_Translation" rows="7" cols="50" allow_html="0"/>
-
+ <inp2:m_RenderElement name="inp_edit_textarea_ml" prefix="phrases" field="Translation" title="la_fld_Translation" rows="3" cols="50" allow_html="0"/>
+
+ <inp2:m_if check="phrases_FieldVisible" field="GoogleTranslation">
+ <tr class="<inp2:m_odd_even odd='edit-form-odd' even='edit-form-even'/>">
+ <inp2:m_inc param="tab_index" by="1"/>
+ <td class="label-cell">
+ <inp2:m_phrase name="la_fld_GoogleTranslation"/>:
+ </td>
+ <td class="control-mid"> </td>
+ <td class="control-cell">
+ <select tabindex="<inp2:m_get param="tab_index"/>" name="<inp2:phrases_InputName field="GoogleTranslationTargetLanguage"/>" id="<inp2:phrases_InputName field="GoogleTranslationTargetLanguage"/>">
+ <inp2:phrases_PredefinedOptions field="GoogleTranslationTargetLanguage" block="inp_option_item" selected="selected"/>
+ </select>
+ <input type="button" id="GetTranslation" name="GetTranslation" value="<inp2:m_phrase name='la_btn_Translate' no_editing='1'/>" onclick="translatePrase();">
+ <span id="translation_results"></span>
+ </td>
+ </tr>
+ <script type="text/javascript">
+ function translatePrase() {
+ var $google_api_key = '<inp2:m_GetConfig name="GoogleTranslateApiKey"/>';
+ if (!$google_api_key.length) {
+ alert('<inp2:m_Phrase name="la_error_GoogleTranslateApiKeyMissing" no_editing="1" js_escape="1"/>');
+ }
+ var $url = '<inp2:m_Link template="dummy" events[phrases]="OnGetGoogleTranslation" q="#TO_TRANSLATE#" target_locale="#TARGET_LOCALE#" no_amp="1" js_escape="1"/>';
+ $.ajax(
+ {
+ type: 'GET',
+ url: $request = $url.replace('#TARGET_LOCALE#', encodeURIComponent($('#'+jq('<inp2:phrases_InputName field="GoogleTranslationTargetLanguage"/>')).val())).replace('#TO_TRANSLATE#', encodeURIComponent($('#'+jq('<inp2:phrases_InputName field="Translation"/>')).val())),
+ success: function ($data) {
+ if ($data.lenght == 0) {
+ // use timeout for selector to be closed
+ setTimeout(
+ function() {
+ alert('<inp2:m_Phrase name="la_error_NoTranslationAvailable" no_editing="1" js_escape="1"/>');
+ }, 0
+ );
+ }
+ else {
+ $('#translation_results').text($data).html();
+ }
+ }
+ }
+ );
+ }
+ </script>
+ </inp2:m_if>
+
<inp2:m_RenderElement name="inp_edit_radio" prefix="phrases" field="PhraseType" title="la_fld_PhraseType"/>
<inp2:m_RenderElement name="inp_edit_options" prefix="phrases" field="Module" title="la_fld_Module"/>
</inp2:m_if>
Index: admin_templates/regional/languages_edit.tpl
===================================================================
--- admin_templates/regional/languages_edit.tpl (revision 14184)
+++ admin_templates/regional/languages_edit.tpl (working copy)
@@ -93,7 +93,7 @@
<td class="control-mid"> </td>
<td class="control-cell">
<input type="hidden" id="<inp2:lang_InputName field="CopyLabels"/>" name="<inp2:lang_InputName field="CopyLabels"/>" value="<inp2:lang_Field field="CopyLabels" db="db"/>">
- <input tabindex="<inp2:m_get param="tab_index"/>" type="checkbox" id="_cb_CopyLabels" name="_cb_CopyLabels" <inp2:lang_Field field="CopyLabels" checked="checked" db="db"/> onclick="update_checkbox(this, document.getElementById('<inp2:lang_InputName field="CopyLabels"/>'))">
+ <input tabindex="<inp2:m_get param="tab_index"/>" type="checkbox" id="_cb_CopyLabels" name="_cb_CopyLabels" <inp2:lang_Field field="CopyLabels" checked="checked" db="db"/> onclick="update_checkbox(this, document.getElementById('<inp2:lang_InputName field="CopyLabels"/>')); reflectAutoTranslateLabels();">
<inp2:m_inc param="tab_index" by="1"/>
<select tabindex="<inp2:m_get param="tab_index"/>" name="<inp2:lang_InputName field="CopyFromLanguage"/>" id="<inp2:lang_InputName field="CopyFromLanguage"/>">
@@ -102,6 +102,23 @@
</select>
</td>
</tr>
+
+ <inp2:m_if check="m_GetConfig" name="GoogleTranslateApiKey">
+ <inp2:m_RenderElement name="inp_edit_checkbox" prefix="lang" field="AutoTranslateLabels" title="la_fld_AutoTranslateLabels" hint_label="la_hint_AutoTranslateLabels"/>
+
+ <script type="text/javascript">
+ function reflectAutoTranslateLabels() {
+ var $field_mask = '<inp2:lang_InputName name="#FIELD_NAME#" js_escape="1"/>';
+ var $copy_labels_status = $('#_cb_CopyLabels').attr('checked');
+ get_control($field_mask, 'AutoTranslateLabels', undefined, '_cb').disabled = !$copy_labels_status;
+ if ( ! $copy_labels_status ) {
+ get_control($field_mask, 'AutoTranslateLabels', undefined, '_cb').checked = false;
+ get_control($field_mask, 'AutoTranslateLabels').value = 0;
+ }
+ }
+ </script>
+ </inp2:m_if>
+
</inp2:m_if>
</inp2:m_if>
Index: install/english.lang
===================================================================
--- install/english.lang (revision 14184)
+++ install/english.lang (working copy)
@@ -46,6 +46,7 @@
<PHRASE Label="la_btn_SelectAll" Module="Core" Type="1">U2VsZWN0IEFsbA==</PHRASE>
<PHRASE Label="la_btn_SetValue" Module="Core" Type="1">U2V0IFZhbHVl</PHRASE>
<PHRASE Label="la_btn_ShowStructure" Module="Core" Type="1">U2hvdyBTdHJ1Y3R1cmU=</PHRASE>
+ <PHRASE Label="la_btn_Translate" Module="Core" Type="1">VHJhbnNsYXRl</PHRASE>
<PHRASE Label="la_btn_Unselect" Module="Core" Type="1">VW5zZWxlY3Q=</PHRASE>
<PHRASE Label="la_btn_Up" Module="Core" Type="1">VXA=</PHRASE>
<PHRASE Label="la_btn_UseDraft" Module="Core" Type="1">VXNl</PHRASE>
@@ -254,6 +255,8 @@
<PHRASE Label="la_config_force_http" Module="Core" Type="1">UmVkaXJlY3QgdG8gSFRUUCB3aGVuIFNTTCBpcyBub3QgcmVxdWlyZWQ=</PHRASE>
<PHRASE Label="la_config_FullImageHeight" Module="Core" Type="1">RnVsbCBpbWFnZSBIZWlnaHQ=</PHRASE>
<PHRASE Label="la_config_FullImageWidth" Module="Core" Type="1">RnVsbCBpbWFnZSBXaWR0aA==</PHRASE>
+ <PHRASE Label="la_config_GoogleTranslateApiKey" Module="Core" Type="1">R29vZ2xlIFRyYW5zbGF0ZSBBUEkgS2V5</PHRASE>
+ <PHRASE Label="la_config_GoogleTranslateApiUrl" Module="Core" Type="1">R29vZ2xlIFRyYW5zbGF0ZSBBUEkgVXJs</PHRASE>
<PHRASE Label="la_config_HTTPAuthBypassIPs" Module="Core" Type="1">QnlwYXNzIEhUVFAgQXV0aGVudGljYXRpb24gZnJvbSBJUHMgKHNlcGFyYXRlZCBieSBzZW1pY29sb25zKQ==</PHRASE>
<PHRASE Label="la_config_HTTPAuthPassword" Module="Core" Type="1">UGFzc3dvcmQgZm9yIEhUVFAgQXV0aGVudGljYXRpb24=</PHRASE>
<PHRASE Label="la_config_HTTPAuthUsername" Module="Core" Type="1">VXNlcm5hbWUgZm9yIEhUVFAgQXV0aGVudGljYXRpb24=</PHRASE>
@@ -328,6 +331,7 @@
<PHRASE Label="la_error_copy_subcategory" Module="Core" Type="1">RXJyb3IgY29weWluZyBzdWJzZWN0aW9ucw==</PHRASE>
<PHRASE Label="la_error_CustomExists" Module="Core" Type="1">Q3VzdG9tIGZpZWxkIHdpdGggaWRlbnRpY2FsIG5hbWUgYWxyZWFkeSBleGlzdHM=</PHRASE>
<PHRASE Label="la_error_FileTooLarge" Module="Core" Type="1">RmlsZSBpcyB0b28gbGFyZ2U=</PHRASE>
+ <PHRASE Label="la_error_GoogleTranslateApiKeyMissing" Module="Core" Type="1">WW91IGFyZSBtaXNzaW5nIHlvdXIgR29vZ2xlIFRyYW5zbGF0ZSBBUEkgS2V5LiBQbGVhc2UgZW50ZXIgaXQgaW4gb3JkZXIgdG8gdXNlIEdvb2dsZSBUcmFuc2xhdGlvbiBzZXJ2aWNlIQ==</PHRASE>
<PHRASE Label="la_error_GroupNotFound" Module="Core" Type="1">Z3JvdXAgbm90IGZvdW5k</PHRASE>
<PHRASE Label="la_error_InvalidFileFormat" Module="Core" Type="1">SW52YWxpZCBGaWxlIEZvcm1hdA==</PHRASE>
<PHRASE Label="la_error_invalidoption" Module="Core" Type="1">aW52YWxpZCBvcHRpb24=</PHRASE>
@@ -336,6 +340,7 @@
<PHRASE Label="la_error_move_subcategory" Module="Core" Type="1">RXJyb3IgbW92aW5nIHN1YnNlY3Rpb24=</PHRASE>
<PHRASE Label="la_error_NoInheritancePossible" Module="Core" Type="1">Q2FuJ3QgaW5oZXJpdCB0ZW1wbGF0ZSBmcm9tIHRvcCBjYXRlZ29yeQ==</PHRASE>
<PHRASE Label="la_error_NoMatchingColumns" Module="Core" Type="1">Tm8gbWF0Y2hpbmcgY29sdW1ucyBhcmUgZm91bmQ=</PHRASE>
+ <PHRASE Label="la_error_NoTranslationAvailable" Module="Core" Type="1">U29ycnksIG5vIHRyYW5zbGF0aW9uIGlzIGF2YWlsYWJsZSE=</PHRASE>
<PHRASE Label="la_error_OperationNotAllowed" Module="Core" Type="1">VGhpcyBvcGVyYXRpb24gaXMgbm90IGFsbG93ZWQh</PHRASE>
<PHRASE Label="la_error_ParsingError" Module="Core" Type="1">VmFsaWRhdGlvbiBlcnJvciwgcGxlYXNlIGRvdWJsZS1jaGVjayBJbi1Qb3J0YWwgdGFncw==</PHRASE>
<PHRASE Label="la_error_PasswordMatch" Module="Core" Type="1">UGFzc3dvcmRzIGRvIG5vdCBtYXRjaCE=</PHRASE>
@@ -389,6 +394,7 @@
<PHRASE Label="LA_FLD_ATTACHMENT" Module="Core" Type="1">QXR0YWNobWVudA==</PHRASE>
<PHRASE Label="la_fld_AutoCreateFileName" Module="Core" Type="1">QXV0byBDcmVhdGUgRmlsZSBOYW1l</PHRASE>
<PHRASE Label="la_fld_AutomaticFilename" Module="Core" Type="1">QXV0b21hdGljIEZpbGVuYW1l</PHRASE>
+ <PHRASE Label="la_fld_AutoTranslateLabels" Module="Core" Type="1">VHJhbnNsYXRlIGFmdGVyIENvcHlpbmc=</PHRASE>
<PHRASE Label="la_fld_AvailableColumns" Module="Core" Type="1">QXZhaWxhYmxlIENvbHVtbnM=</PHRASE>
<PHRASE Label="la_fld_Background" Module="Core" Type="1">QmFja2dyb3VuZA==</PHRASE>
<PHRASE Label="la_fld_BackgroundAttachment" Module="Core" Type="1">QmFja2dyb3VuZCBBdHRhY2htZW50</PHRASE>
@@ -491,6 +497,7 @@
<PHRASE Label="la_fld_FromEmail" Module="Core" Type="1">RnJvbSBFbWFpbA==</PHRASE>
<PHRASE Label="la_fld_FrontEndOnly" Module="Core" Type="1">RnJvbnQtRW5kIE9ubHk=</PHRASE>
<PHRASE Label="la_fld_FrontRegistration" Module="Core" Type="1">QWxsb3cgUmVnaXN0cmF0aW9uIG9uIEZyb250LWVuZA==</PHRASE>
+ <PHRASE Label="la_fld_GoogleTranslation" Module="Core" Type="1">R29vZ2xlIFRyYW5zbGF0aW9u</PHRASE>
<PHRASE Label="la_fld_Group" Module="Core" Type="1">VXNlciBHcm91cA==</PHRASE>
<PHRASE Label="la_fld_GroupId" Module="Core" Type="1">SUQ=</PHRASE>
<PHRASE Label="la_fld_GroupName" Module="Core" Type="1">R3JvdXAgTmFtZQ==</PHRASE>
@@ -697,6 +704,7 @@
<PHRASE Label="la_HeadFrame" Module="Core" Type="1">SGVhZCBGcmFtZQ==</PHRASE>
<PHRASE Label="la_Hide" Module="Core" Type="1">SGlkZQ==</PHRASE>
<PHRASE Label="la_hint_AllFiles" Module="Core" Type="1">QWxsIEZpbGVz</PHRASE>
+ <PHRASE Label="la_hint_AutoTranslateLabels" Module="Core" Type="1">QWxsIExhYmVscyB3aWxsIGJlIGF1dG8tdHJhbnNsYXRlZCB1c2luZyBHb29nbGUgVHJhbnNsYXRlIFNlcnZpY2Ugb25jZSBuZXcgbGFuZ3VhZ2UgaXMgY3JlYXRlZCBhbmQgbGFiZWxzIGNvcGllZC4gQXV0by10cmFuc2xhdGUgd2lsbCB3b3JrIG9ubHkgaWYgIkNvcHkgTGFiZWxzIGZyb20gdGhpcyBMYW5ndWFnZSIgb3B0aW9uIGlzIGNoZWNrZWQu</PHRASE>
<PHRASE Label="la_hint_CSVFiles" Module="Core" Type="1">Q1NWIEZpbGVz</PHRASE>
<PHRASE Label="la_hint_DomainIPRange" Module="Core" Type="1">U2luZ2xlIElQIG9yIHJhbmdlIHJlY29yZCBwZXIgbGluZSAoZm9ybWF0czogMS4yLjMuNCBvciAxLjIuMyBvciAxLjIuMy4zMi0xLjIuMy41NCBvciAxLjIuMy4zMi8yNyBvciAxLjIuMy4zMi8yNTUuMjU1LjI1NS4yMjQp</PHRASE>
<PHRASE Label="la_hint_ExportEmailEvents" Module="Core" Type="1">U2luZ2xlIEVtYWlsIEV2ZW50IHBlciBsaW5lIChmb3JtYXRzOiBVU0VSLkFERCwgT1JERVIuU1VCTUlUKQ==</PHRASE>
@@ -1075,6 +1083,7 @@
<PHRASE Label="la_section_ReplacementTags" Module="Core" Type="1">UmVwbGFjZW1lbnQgVGFncw==</PHRASE>
<PHRASE Label="la_section_SenderInfo" Module="Core" Type="1">U2VuZGVyIEluZm9ybWF0aW9u</PHRASE>
<PHRASE Label="la_section_Settings" Module="Core" Type="1">U2V0dGluZ3M=</PHRASE>
+ <PHRASE Label="la_section_Settings3rdPartyApi" Module="Core" Type="1">M3JkIFBhcnR5IEFQSSBTZXR0aW5ncw==</PHRASE>
<PHRASE Label="la_section_SettingsAdmin" Module="Core" Type="1">QWRtaW4gQ29uc29sZSBTZXR0aW5ncw==</PHRASE>
<PHRASE Label="la_section_SettingsCaching" Module="Core" Type="1">Q2FjaGluZyBTZXR0aW5ncw==</PHRASE>
<PHRASE Label="la_section_SettingsCSVExport" Module="Core" Type="1">Q1NWIEV4cG9ydCBTZXR0aW5ncw==</PHRASE>
Index: install/install_data.sql
===================================================================
--- install/install_data.sql (revision 14184)
+++ install/install_data.sql (working copy)
@@ -94,6 +94,8 @@
INSERT INTO ConfigurationValues VALUES(DEFAULT, 'CSVExportEncoding', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsCSVExport', 'la_config_CSVExportEncoding', 'radio', NULL, '0=la_Unicode||1=la_Regular', 70.04, 0, 1, NULL);
INSERT INTO ConfigurationValues VALUES(DEFAULT, 'CacheHandler', 'Fake', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsCaching', 'la_config_CacheHandler', 'select', NULL, 'Fake=la_None||Memcache=+Memcached||Apc=+Alternative PHP Cache||XCache=+XCache', 80.01, 0, 0, NULL);
INSERT INTO ConfigurationValues VALUES(DEFAULT, 'MemcacheServers', 'localhost:11211', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsCaching', 'la_config_MemcacheServers', 'text', NULL, '', 80.02, 0, 0, 'la_hint_MemcacheServers');
+INSERT INTO ConfigurationValues VALUES(DEFAULT, 'GoogleTranslateApiUrl', 'https://www.googleapis.com/language/translate/v2', 'In-Portal', 'in-portal:configure_advanced', 'la_section_Settings3rdPartyApi', 'la_config_GoogleTranslateApiUrl', 'text', NULL, '', 90.01, 0, 0, NULL);
+INSERT INTO ConfigurationValues VALUES(DEFAULT, 'GoogleTranslateApiKey', '', 'In-Portal', 'in-portal:configure_advanced', 'la_section_Settings3rdPartyApi', 'la_config_GoogleTranslateApiKey', 'text', NULL, '', 90.02, 0, 0, NULL);
# Section "in-portal:configure_users":
INSERT INTO ConfigurationValues VALUES(DEFAULT, 'User_Allow_New', '3', 'In-Portal:Users', 'in-portal:configure_users', 'la_title_General', 'la_users_allow_new', 'radio', '', '1=la_opt_UserInstantRegistration||2=la_opt_UserNotAllowedRegistration||3=la_opt_UserUponApprovalRegistration||4=la_opt_UserEmailActivation', 10.01, 0, 1, NULL);
Index: units/languages/languages_config.php
===================================================================
--- units/languages/languages_config.php (revision 14184)
+++ units/languages/languages_config.php (working copy)
@@ -216,6 +216,7 @@
'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Language ORDER BY PackName', 'option_title_field' => 'PackName', 'option_key_field' => 'LanguageId',
'default' => '',
),
+ 'AutoTranslateLabels' => Array ('type' => 'int', 'default' => 0),
),
'Grids' => Array(
Index: units/languages/languages_event_handler.php
===================================================================
--- units/languages/languages_event_handler.php (revision 14184)
+++ units/languages/languages_event_handler.php (working copy)
@@ -249,10 +249,10 @@
$object =& $event->getObject();
/* @var $object kDBItem */
- $src_language = $object->GetDBField('CopyFromLanguage');
+ $src_language_id = $object->GetDBField('CopyFromLanguage');
- if ($object->GetDBField('CopyLabels') && $src_language) {
- $dst_language = $object->GetID();
+ if ($object->GetDBField('CopyLabels') && $src_language_id) {
+ $dst_language_id = $object->GetID();
// 1. schedule data copy after OnSave event is executed
$var_name = $event->getPrefixSpecial() . '_copy_data' . $this->Application->GetVar('m_wid');
@@ -261,10 +261,25 @@
if ($pending_actions) {
$pending_actions = unserialize($pending_actions);
}
-
- $pending_actions[$src_language] = $dst_language;
+
+ $pending_actions[$src_language_id] = Array( 'target_id' => $dst_language_id );
+
+ if ( $object->GetDBField('AutoTranslateLabels') ) {
+ $live_table = $this->Application->getUnitOption($event->Prefix, 'TableName');
+ $sql = 'SELECT Locale FROM ' . $live_table . '
+ WHERE ' . $object->IDField. ' = ' . $src_language_id;
+ $src_lang_locale = $this->Conn->GetOne($sql);
+
+ if ( $src_lang_locale ) {
+ $pending_actions[$src_language_id]['source_locale'] = strstr($src_lang_locale, '-', true); // save the locale for later
+ $pending_actions[$src_language_id]['target_locale'] = strstr($object->GetDBField('Locale'), '-', true); // save the locale for later
+ }
+ }
+
$this->Application->StoreVar($var_name, serialize($pending_actions));
+
$object->SetDBField('CopyLabels', 0);
+ $object->SetDBField('AutoTranslateLabels', 0);
}
}
@@ -280,6 +295,9 @@
if ($event->status != erSUCCESS) {
return ;
}
+
+ $object =& $event->getObject();
+ /* @var $object kDBItem */
$var_name = $event->getPrefixSpecial() . '_copy_data' . $this->Application->GetVar('m_wid');
$pending_actions = $this->Application->RecallVar($var_name, Array ());
@@ -293,7 +311,9 @@
$ml_helper->createFields('phrases');
$ml_helper->createFields('emailevents');
- foreach ($pending_actions as $src_language => $dst_language) {
+ foreach ($pending_actions as $src_language => $lang_data) {
+ $dst_language = $lang_data['target_id'];
+
// phrases import
$sql = 'UPDATE ' . $this->Application->getUnitOption('phrases', 'TableName') . '
SET l' . $dst_language . '_Translation = l' . $src_language . '_Translation';
@@ -305,6 +325,14 @@
l' . $dst_language . '_Subject = l' . $src_language . '_Subject,
l' . $dst_language . '_Body = l' . $src_language . '_Body';
$this->Conn->Query($sql);
+
+ if ( isset($lang_data['source_locale']) ) {
+ // perform the translations
+ $event->setEventParam('source_locale', $lang_data['source_locale']);
+ $event->setEventParam('target_locale', $lang_data['target_locale']);
+ $event->setEventParam('target_lang_id', $dst_language);
+ $event->CallSubEvent('OnTranslateLanguagePack');
+ }
}
$this->Application->RemoveVar($var_name);
@@ -314,6 +342,137 @@
}
/**
+ * Performs actual translation and data update
+ *
+ * @param string $prefix
+ * @param array $data
+ * @param int $lang_id
+ * @param string $source_locale
+ * @param string $target_locale
+ */
+ function _performTranslation($prefix, $data, $lang_id, $source_locale, $target_locale)
+ {
+ $post_data = '';
+ $counter = 0;
+ $posting_limits = ($prefix == 'phrases')? 100 : 50; // limits are: 100 phrases or 50 email events (subject + body)
+ $table = $this->Application->getUnitOption($prefix, 'TableName');
+
+ $url = $this->Application->ConfigValue('GoogleTranslateApiUrl') . '?key=' . $this->Application->ConfigValue('GoogleTranslateApiKey') . '&prettyprint=true&source=' . $source_locale . '&target=' . $target_locale;
+ $curl_helper =& $this->Application->recallObject('CurlHelper');
+ /* @var $curl_helper kCurlHelper */
+
+ foreach ($data as $data_id => $source) {
+ if ($prefix == 'phrases') {
+ $post_data .= 'q=' . rawurlencode($source) . '&';
+ }
+ else {
+ $post_data .= 'q=' . rawurlencode($source['l'.$lang_id.'_Subject']) . '&q=' . rawurlencode($source['l'.$lang_id.'_Body']) . '&'; // email subject and boby
+ }
+
+ $counter++;
+ $ids[] = $data_id; // save ids we are going to translate in this round for later
+
+ if ( count($ids) == $posting_limits || count($data) == $counter || strlen($post_data) > 4500) {
+ // with single Curl request process 100 or phrases or 4.5K (API POST data limits)
+ $curl_helper->followLocation = true;
+ $curl_helper->SetHeader('X-HTTP-Method-Override', 'GET'); // see - http://code.google.com/apis/language/translate/v2/using_rest.html#WorkingResults
+ $curl_helper->SetPostData($post_data);
+
+ $response = $curl_helper->Send( $url );
+
+ if ( $response ) {
+ $parsed_response = json_decode($response, true);
+ $translations = $parsed_response['data']['translations']; // array of translations
+
+ if ( isset($translations) && is_array($translations) ) {
+ $where_case = '';
+ $where_case1 = '';
+
+ foreach ($translations as $index => $translation) {
+ // build multiple translation updates into one SQL
+ if ( $translation ) {
+ if ($prefix == 'phrases') {
+ $where_case .= ' WHEN ' . $ids[ $index ] . ' THEN ' . $this->Conn->qstr($translation['translatedText']);
+ }
+ elseif ($prefix == 'emailevents') {
+ // do this go through all odd array records to be case for body
+ // since we are processing both subject and body that belong to one event record
+ $even = $index % 2? FALSE : TRUE;
+ if ( $even ) {
+ $event_id = $index / 2;
+ $where_case .= ' WHEN ' . $ids[ $event_id ] . ' THEN ' . $this->Conn->qstr($translation['translatedText']);
+ }
+ else {
+ $where_case1 .= ' WHEN ' . $ids[ $event_id ] . ' THEN ' . $this->Conn->qstr($translation['translatedText']);
+ }
+ }
+ }
+ else {
+ // translation is missing
+ unset($ids[ $index ]);
+ }
+ }
+
+ if ($prefix == 'phrases' && $where_case) {
+ $sql = 'UPDATE ' . $table . '
+ SET l' . $lang_id . '_Translation = CASE PhraseId ' . $where_case . ' END
+ WHERE PhraseId IN (' . implode(',', $ids) . ')';
+ $this->Conn->Query($sql);
+ }
+ elseif ($prefix == 'emailevents' && ($where_case || $where_case1)) {
+ $sql = 'UPDATE ' . $table . '
+ SET l' . $lang_id . '_Subject = CASE EventId ' . $where_case . ' END, l' . $lang_id . '_Body = CASE EventId ' . $where_case1 . ' END
+ WHERE EventId IN (' . implode(',', $ids) . ')';
+ $this->Conn->Query($sql);
+ }
+ }
+ // reset variables so we can prepare a new request
+ $post_data = '';
+ unset($ids);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Auto-translate language labels using Google Translate API
+ *
+ * @param kEvent $event
+ */
+ function OnTranslateLanguagePack(&$event)
+ {
+ $lang_id = $event->getEventParam('target_lang_id');
+ $source_locale = $event->getEventParam('source_locale');
+ $target_locale = $event->getEventParam('target_locale');
+
+ // 1. translate language phrases
+ $table = $this->Application->getUnitOption('phrases', 'TableName');
+ $sql = 'SELECT l' . $lang_id . '_Translation, PhraseId
+ FROM ' . $table . '
+ WHERE l' . $lang_id . '_Translation != \'\' AND l' . $lang_id . '_Translation IS NOT NULL
+ ORDER BY PhraseId';
+
+ $phrases_to_translate = $this->Conn->GetCol($sql, 'PhraseId');
+ if ( $phrases_to_translate ) {
+ $this->_performTranslation('phrases', $phrases_to_translate, $lang_id, $source_locale, $target_locale);
+ }
+
+ // 2. translate language events
+ $table = $this->Application->getUnitOption('emailevents', 'TableName');
+ $sql = 'SELECT l' . $lang_id . '_Subject, l' . $lang_id . '_Body, EventId
+ FROM ' . $table . '
+ WHERE (l' . $lang_id . '_Subject != \'\' AND l' . $lang_id . '_Subject IS NOT NULL) OR
+ (l' . $lang_id . '_Body != \'\' AND l' . $lang_id . '_Body IS NOT NULL)
+ ORDER BY EventId';
+
+ $events_to_translate = $this->Conn->Query($sql, 'EventId');
+ if ( $events_to_translate ) {
+ $this->_performTranslation('emailevents', $events_to_translate, $lang_id, $source_locale, $target_locale);
+ }
+ }
+
+ /**
* Prepare temp tables for creating new item
* but does not create it. Actual create is
* done in OnPreSaveCreated
Index: units/phrases/phrases_config.php
===================================================================
--- units/phrases/phrases_config.php (revision 14184)
+++ units/phrases/phrases_config.php (working copy)
@@ -159,6 +159,12 @@
),
'ExportPhrases' => Array ('type' => 'string', 'default' => ''),
'ExportEmailEvents' => Array ('type' => 'string', 'default' => ''),
+
+ 'GoogleTranslation' => Array ('type' => 'string', 'default' => ''),
+ 'GoogleTranslationTargetLanguage' => Array (
+ 'type' => 'string',
+ 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT PackName, SUBSTR(Locale, 1, 2) AS Target FROM ' . TABLE_PREFIX . 'Language WHERE (Locale != "") ORDER BY PrimaryLang DESC, Priority DESC', 'option_key_field' => 'Target', 'option_title_field' => 'PackName',
+ ),
),
'Grids' => Array (
Index: units/phrases/phrases_event_handler.php
===================================================================
--- units/phrases/phrases_event_handler.php (revision 14184)
+++ units/phrases/phrases_event_handler.php (working copy)
@@ -55,6 +55,11 @@
return true;
}
}
+
+ if ($this->Application->isAdmin && $event->Name == 'OnGetGoogleTranslation') {
+ // request to google translation api
+ return true;
+ }
return parent::CheckPermission($event);
}
@@ -329,4 +334,31 @@
// use language from grid, instead of primary language used by default
$event->SetRedirectParam('m_lang', $this->Application->GetVar('m_lang'));
}
+
+ /**
+ * Send request to Google Translate API to translate text
+ *
+ * @param kEvent $event
+ */
+ function OnGetGoogleTranslation(&$event)
+ {
+ $curl_helper =& $this->Application->recallObject('CurlHelper');
+ /* @var $curl_helper kCurlHelper */
+
+ $target_locale = $this->Application->GetVar('target_locale');
+ $to_translate = rawurlencode( $this->Application->GetVar('q') );
+
+ $request_url = $this->Application->ConfigValue('GoogleTranslateApiUrl') . '?key=' . $this->Application->ConfigValue('GoogleTranslateApiKey') . '&target=' . $target_locale . '&q=' . $to_translate;
+
+ $response = $curl_helper->Send($request_url);
+
+ if ( $response ) {
+ $parsed_response = json_decode($response, true);
+ if ( isset($parsed_response['data']['translations'][0]['translatedText']) ) {
+ echo $parsed_response['data']['translations'][0]['translatedText'];
+ }
+ }
+
+ $event->status = erSTOP;
+ }
}
\ No newline at end of file