public function ExportFile($strTemplate, $strTranslatedFile) { if ($strTemplateFileContents = file_get_contents($strTemplate)) { $arrTemplate = array(); if (preg_match_all('/([^$]+)\\$([^\\s]+)\\s*=\\s*([\']?.*[\']?);(.*)/m', $strTemplateFileContents, $arrTemplateMatches)) { foreach ($arrTemplateMatches[2] as $intKey => $strIdentifier) { if (trim(preg_replace('/^\'(.*)\'$/', '\\1', $arrTemplateMatches[3][$intKey]))) { $strText = preg_replace('/^\'(.*)\'$/', '\\1', $arrTemplateMatches[3][$intKey]); $strContext = $arrTemplateMatches[1][$intKey] . $arrTemplateMatches[2][$intKey] . $arrTemplateMatches[4][$intKey]; $objNarroContextInfo = $this->GetContextInfo($strText, trim($strContext)); if ($objNarroContextInfo->ValidSuggestionId) { /** * @todo replace the following code with a replacement of the full line */ $strNewBlock = NarroString::Replace("= '" . $strText . "'", "= '" . $objNarroContextInfo->ValidSuggestion->SuggestionValue . "'", $arrTemplateMatches[0][$intKey], 1); $strTemplateFileContents = str_replace($arrTemplateMatches[0][$intKey], $strNewBlock, $strTemplateFileContents); } } } file_put_contents($strTranslatedFile, $strTemplateFileContents); } } else { NarroLogger::LogError(sprintf('Cannot open file "%s".', $strFileToImport)); } }
public function __construct($objParentObject, $strControlId = null, NarroContextInfo $objContextInfo) { parent::__construct($objParentObject, $strControlId); $this->objContextInfo = $objContextInfo; $this->lblIndex = new QLabel($this); $this->lblIndex->CssClass = 'index'; $this->lblIndex->HtmlEntities = false; $this->lblMessage = new QLabel($this); $this->lblMessage->CssClass = 'message'; $this->lblMessage->HtmlEntities = false; $this->chkChanged = new QCheckBox($this); $this->chkChanged->DisplayStyle = QDisplayStyle::None; $this->txtTranslation = new QTextBox($this); $this->txtTranslation->ActionParameter = $objContextInfo->ContextInfoId; $this->txtTranslation->TextMode = QTextMode::MultiLine; $this->txtTranslation->CssClass = 'translation_box'; $this->txtTranslation->CrossScripting = QCrossScripting::Allow; $this->txtTranslation->Rows = 1; $this->txtTranslation->ReadOnly = !QApplication::HasPermissionForThisLang('Can suggest'); $this->txtTranslation->Width = '100%'; $this->txtTranslation->DisplayStyle = QDisplayStyle::Block; if ($this->txtTranslation->ReadOnly) { $this->txtTranslation->ToolTip = t('Sign in to add translations'); } else { $this->txtTranslation->ToolTip = t('Enter your translation here'); } if ($this->objContextInfo->Context->TextAccessKey) { $this->txtAccessKey = new QTextBox($this); $this->txtAccessKey->ToolTip = sprintf(t('Access key (original access key: %s)'), $this->objContextInfo->Context->TextAccessKey); $this->txtAccessKey->TextMode = QTextMode::SingleLine; $this->txtAccessKey->Name = t('Access key'); $this->txtAccessKey->Instructions = sprintf(t('This is the letter that appears underlined in menus and buttons and you can use Alt + this letter to select, e.g. <b>%s</b>'), NarroString::Replace($this->objContextInfo->Context->TextAccessKey, sprintf('<u>%s</u>', $this->objContextInfo->Context->TextAccessKey), $this->objContextInfo->Context->Text->TextValue, 1)); $this->txtAccessKey->Columns = 5; $this->txtAccessKey->MaxLength = 10; $this->txtAccessKey->Text = $this->objContextInfo->SuggestionAccessKey; } if ($this->objContextInfo->Context->TextCommandKey) { $this->txtCommandKey = new QTextBox($this); $this->txtCommandKey->ToolTip = sprintf(t('Command key (original command key: %s)'), $this->objContextInfo->Context->TextCommandKey); $this->txtCommandKey->TextMode = QTextMode::SingleLine; $this->txtCommandKey->Name = t('Command key'); $this->txtCommandKey->Instructions = sprintf(t('This is the letter that appears in menus and buttons after the text and you can use Ctrl + this letter to select, e.g. <b>%s Ctrl+%s</b>'), NarroString::Replace($this->objContextInfo->Context->TextAccessKey, sprintf('<u>%s</u>', $this->objContextInfo->Context->TextAccessKey), $this->objContextInfo->Context->Text->TextValue, 1), $this->objContextInfo->Context->TextCommandKey); $this->txtCommandKey->Columns = 5; $this->txtCommandKey->MaxLength = 10; $this->txtCommandKey->Text = $this->objContextInfo->SuggestionCommandKey; } if ($objContextInfo->ValidSuggestionId) { $this->txtTranslation->Text = $objContextInfo->ValidSuggestion->SuggestionValue; } $this->txtTranslation->Columns = 50; $this->btnCopy = new QButton($this); $this->btnCopy->Text = t('Copy'); $this->btnCopy->DisplayStyle = QDisplayStyle::None; $this->btnCopy->TabIndex = -1; $this->btnCopy->CssClass = $this->btnCopy->CssClass . ' copy'; $this->btnCopy->Display = QApplication::HasPermissionForThisLang('Can suggest'); $this->lblText = new QLabel($this); $this->lblText->Width = '100%'; $this->lblText->TagName = 'pre'; $this->lblText->CssClass = 'originalText'; $this->lblText->Text = NarroString::ShowLeadingAndTrailingSpaces(NarroString::HtmlEntities($this->objContextInfo->Context->Text->TextValue)); $this->lblText->HtmlEntities = false; $this->lblText->Text = str_replace("\n", '<span class="newline_block" title="Enter"> </span><br />', $this->lblText->Text); $this->btnHelp_Create(); $this->btnSave = new QButton($this); $this->btnSave->Text = t('Save'); $this->btnSave->CssClass = $this->btnSave->CssClass . ' save'; $this->btnSave->Display = QApplication::HasPermissionForThisLang('Can suggest'); if (QApplication::$User->GetPreferenceValueByName('Automatically save translations') == 'Yes') { $this->btnSave->DisplayStyle = QDisplayStyle::None; $this->btnSave->TabIndex = -1; } $this->btnSave->AddAction(new QClickEvent(), new QAjaxControlAction($this, 'btnSave_Click')); $this->btnKeepUntranslated_Create(); $this->lblContextInfo_Create(); $this->txtTranslation->AddAction(new QFocusEvent(), new QJavaScriptAction(sprintf('ctx_editor_focus("%s", "%s", "%s", "%s", "%s", "%s")', $this->ControlId, $this->txtTranslation->ControlId, $this->btnCopy->ControlId, $this->btnHelp->ControlId, $this->lblContextInfo->ControlId, $this->chkChanged->ControlId))); $this->txtTranslation->AddAction(new QChangeEvent(), new QJavaScriptAction(sprintf('jQuery("#%s").attr("checked", true);', $this->chkChanged->ControlId))); if (QApplication::$User->GetPreferenceValueByName('Automatically save translations') == 'Yes') { $this->txtTranslation->AddAction(new QFocusEvent(), new QAjaxControlAction($this, 'txtTranslation_Focus')); } $this->btnCopy->AddAction(new QClickEvent(), new QJavaScriptAction(sprintf('if (jQuery("#%s").attr("alt") == "%s") {jQuery("#%s").val(jQuery("#%s").text());jQuery("#%s").attr("alt", "%s");jQuery("#%s").attr("checked", "true");} else {jQuery("#%s").val("");jQuery("#%s").attr("alt", "%s");jQuery("#%s").attr("checked", "");}', $this->btnCopy->ControlId, t('Copy'), $this->txtTranslation->ControlId, $this->lblText->ControlId, $this->btnCopy->ControlId, t('Clear'), $this->chkChanged->ControlId, $this->txtTranslation->ControlId, $this->btnCopy->ControlId, t('Copy'), $this->chkChanged->ControlId))); if ($this->objContextInfo->HasSuggestions && is_null($this->objContextInfo->ValidSuggestionId)) { $this->dtgTranslation_Create(); } $this->strTemplate = dirname(__FILE__) . '/' . __CLASS__ . '.tpl.php'; if ($this->txtTranslation->ReadOnly) { $this->btnHelp_Click($this->Form->FormId, $this->btnHelp->ControlId, ''); } }
/** * This function looks for accesskey entries and creates po style texts, e.g. &File * @param array $arrTexts an array with context as keys and texts as values */ public function GetAccessKeys($arrTexts) { $arrTexts = parent::GetAccessKeys($arrTexts); foreach ($arrTexts as $strContext => $objEntity) { if (preg_match('/&([a-z0-9])/i', html_entity_decode($objEntity->Value), $arrMatches)) { $objEntity->AccessKey = $arrMatches[1]; $arrTexts[$strContext]->Value = NarroString::Replace($arrMatches[0], $arrMatches[1], $objEntity->Value, 1); } } return $arrTexts; }
/** * A translation here consists of the project, file, text, translation, context, plurals, approval, ignore equals * * @param string $strOriginal the original text * @param string $strOriginalAccKey access key for the original text * @param string $strTranslation the translated text from the import file (can be empty) * @param string $strOriginalAccKey access key for the translated text * @param string $strContext the context where the text/translation appears in the file * @param string $intPluralForm if this is a plural, what plural form is it (0 singular, 1 plural form 1, and so on) * @param string $strComment a comment from the imported file * * @return string valid suggestion */ protected function GetTranslation($strOriginal, $strOriginalAccKey = null, $strOriginalAccKeyPrefix = null, $strTranslation, $strTranslationAccKey = null, $strContext, $strComment = null) { /** * The contexts are trimmed at import to avoid useless white space contexts, so we need to trim it when searching for it as well */ $strContext = trim($strContext); if ($strContext != '') { $objNarroContextInfo = NarroContextInfo::QuerySingle(QQ::AndCondition(QQ::Equal(QQN::NarroContextInfo()->Context->ProjectId, $this->objProject->ProjectId), QQ::Equal(QQN::NarroContextInfo()->Context->FileId, $this->objFile->FileId), QQ::Equal(QQN::NarroContextInfo()->Context->Active, 1), QQ::Equal(QQN::NarroContextInfo()->Context->File->Active, 1), QQ::Equal(QQN::NarroContextInfo()->Context->TextAccessKey, $strOriginalAccKey), QQ::Equal(QQN::NarroContextInfo()->Context->ContextMd5, md5($strContext)), QQ::Equal(QQN::NarroContextInfo()->Context->Text->TextValueMd5, md5($strOriginal)), QQ::Equal(QQN::NarroContextInfo()->LanguageId, $this->objTargetLanguage->LanguageId))); } else { $objNarroContextInfo = NarroContextInfo::QuerySingle(QQ::AndCondition(QQ::Equal(QQN::NarroContextInfo()->Context->ProjectId, $this->objProject->ProjectId), QQ::Equal(QQN::NarroContextInfo()->Context->FileId, $this->objFile->FileId), QQ::Equal(QQN::NarroContextInfo()->Context->Active, 1), QQ::Equal(QQN::NarroContextInfo()->Context->File->Active, 1), QQ::Equal(QQN::NarroContextInfo()->Context->TextAccessKey, $strOriginalAccKey), QQ::Equal(QQN::NarroContextInfo()->Context->Text->TextValueMd5, md5($strOriginal)), QQ::Equal(QQN::NarroContextInfo()->LanguageId, $this->objTargetLanguage->LanguageId))); } if ($objNarroContextInfo instanceof NarroContextInfo) { $this->objCurrentContext = $objNarroContextInfo; $strSuggestionValue = $this->GetExportedSuggestion($objNarroContextInfo); if ($strSuggestionValue !== false) { $arrResult = QApplication::$PluginHandler->ExportSuggestion($strOriginal, $strSuggestionValue, $strContext, $this->objFile, $this->objProject); if ($arrResult[1] != '' && $arrResult[0] == $strOriginal && $arrResult[2] == $strContext && $arrResult[3] == $this->objFile && $arrResult[4] == $this->objProject) { $strSuggestionValue = $arrResult[1]; } else { NarroLogger::LogWarn(sprintf('The plugin "%s" returned an unexpected result while processing the suggestion "%s": %s', QApplication::$PluginHandler->CurrentPluginName, $strSuggestionValue, join(';', $arrResult))); } if (!is_null($strOriginalAccKey) && !is_null($strOriginalAccKeyPrefix)) { /** * @todo don't export if there's no valid access key */ $strTextWithAccKey = NarroString::Replace($objNarroContextInfo->SuggestionAccessKey, $strOriginalAccKeyPrefix . $objNarroContextInfo->SuggestionAccessKey, $strSuggestionValue, 1); return $strTextWithAccKey; } else { return $strSuggestionValue; } } else { // NarroLogger::LogDebug(sprintf('No translation found for the text "%s", while searching for context "%s"', $strOriginal, $strContext)); return ''; } } else { NarroLogger::LogError(sprintf('No context found for the text "%s", while searching for context "%s"', $strOriginal, $strContext)); return ''; } }
/** * A translation here consists of the project, file, text, translation, context, plurals, approval, ignore equals * * @param string $strOriginal the original text * @param string $strOriginalAccKey access key for the original text * @param string $strTranslation the translated text from the import file (can be empty) * @param string $strOriginalAccKey access key for the translated text * @param string $strContext the context where the text/translation appears in the file * @param string $intPluralForm if this is a plural, what plural form is it (0 singular, 1 plural form 1, and so on) * @param string $strComment a comment from the imported file * * @return string valid suggestion */ protected function GetTranslation($strOriginal, $strOriginalAccKey = null, $strOriginalAccKeyPrefix = null, $strTranslation, $strTranslationAccKey = null, $strContext, $strComment = null) { $objNarroContextInfo = NarroContextInfo::QuerySingle(QQ::AndCondition(QQ::Equal(QQN::NarroContextInfo()->Context->ProjectId, $this->objProject->ProjectId), QQ::Equal(QQN::NarroContextInfo()->Context->FileId, $this->objFile->FileId), QQ::Equal(QQN::NarroContextInfo()->Context->ContextMd5, md5(trim($strContext))), QQ::Equal(QQN::NarroContextInfo()->Context->Text->TextValueMd5, md5($strOriginal)), QQ::Equal(QQN::NarroContextInfo()->LanguageId, $this->objTargetLanguage->LanguageId))); if ($objNarroContextInfo instanceof NarroContextInfo) { $strSuggestionValue = $this->GetExportedSuggestion($objNarroContextInfo); $arrResult = QApplication::$PluginHandler->ExportSuggestion($strOriginal, $strSuggestionValue, $strContext, $this->objFile, $this->objProject); if ($arrResult[1] != '' && $arrResult[0] == $strOriginal && $arrResult[2] == $strContext && $arrResult[3] == $this->objFile && $arrResult[4] == $this->objProject) { $strSuggestionValue = $arrResult[1]; } else { NarroLogger::LogWarn(sprintf('The plugin "%s" returned an unexpected result while processing the suggestion "%s": %s', QApplication::$PluginHandler->CurrentPluginName, $strTranslation, $strTranslation)); } if (!is_null($strOriginalAccKey) && !is_null($strOriginalAccKeyPrefix)) { /** * @todo don't export if there's no valid access key */ $strTextWithAccKey = NarroString::Replace($objNarroContextInfo->SuggestionAccessKey, $strOriginalAccKeyPrefix . $objNarroContextInfo->SuggestionAccessKey, $strSuggestionValue, 1); return $strTextWithAccKey; } else { return $strSuggestionValue; } } else { /** * leave it untranslated */ return $strOriginal; } }
public function ExportFile($strTemplateFile, $strTranslatedFile) { $hndTranslatedFile = @fopen($strTranslatedFile, 'w'); if (!$hndTranslatedFile) { throw new Exception(sprintf('Can\'t open file "%s" for writing', $strTranslatedFile)); } $intTotalToProcess = NarroUtils::CountFileLines($strTemplateFile); /** * get all the texts and contexts from the template file, including the file line */ $arrTexts = $this->FileToArray($strTemplateFile, $this->objSourceLanguage->LanguageCode, true); // NarroLogger::LogDebug(sprintf('Starting to process file "%s" (%d texts), the result is written to "%s".', $strTemplateFile, $intTotalToProcess, $strTranslatedFile)); $intFileLineNr = 0; foreach ($arrTexts as $strContext => $arrTextInfo) { $strText = $arrTextInfo[0]; $strTextAccKey = $arrTextInfo[1]; $strTextAccKeyPrefix = $arrTextInfo[2]; $strFileLine = $arrTextInfo[3]; $intFileLineNr++; $arrColumn = preg_split('/\\t/', $strFileLine); /** * Unset a number before language code */ $arrColumn[8] = ''; /** * create a copy for the translated line, we'll just replace lang code, the number on column 8 and the text with the translation */ $arrTranslatedColumn = $arrColumn; $arrTranslatedColumn[8] = 0; $arrTranslatedColumn[9] = 'ro'; $objNarroContextInfo = $this->GetContextInfo($strText, $strContext); if (!$objContextInfo) { // NarroLogger::LogDebug('No context info found, trying database'); $objContextInfo = NarroContextInfo::QueryArray(QQ::AndCondition(QQ::Equal(QQN::NarroContextInfo()->Context->FileId, $this->objFile->FileId), QQ::Equal(QQN::NarroContextInfo()->LanguageId, $this->objTargetLanguage->LanguageId), QQ::Equal(QQN::NarroContextInfo()->Context->Text->TextValueMd5, md5($strText)), QQ::Equal(QQN::NarroContextInfo()->Context->ContextMd5, md5($strContext)))); } /** * the original texts are used if no suggestion is found, so we export only approved texts */ if ($objNarroContextInfo instanceof NarroContextInfo) { $strSuggestionValue = $this->GetExportedSuggestion($objNarroContextInfo); } else { // NarroLogger::LogDebug('No context info found, skipping'); continue; } if (!isset($strSuggestionValue) || !$strSuggestionValue) { continue; } if ($objNarroContextInfo->Context->TextAccessKey != '') { if ($objNarroContextInfo->ValidSuggestionId && $objNarroContextInfo->SuggestionAccessKey != '') { $strSuggestionValue = NarroString::Replace($objNarroContextInfo->SuggestionAccessKey, $strTextAccKeyPrefix . $objNarroContextInfo->SuggestionAccessKey, $strSuggestionValue, 1); } else { $strSuggestionValue = $strTextAccKeyPrefix . $strSuggestionValue; } } $arrTranslatedColumn[10] = str_replace(array("\n", "\r"), array("", ""), $strSuggestionValue); preg_match_all('/\\\\"/', $strText, $arrEscOrigMatches); preg_match_all('/\\\\"/', $strSuggestionValue, $arrEscTransMatches); if (isset($arrEscOrigMatches[0]) && count($arrEscTransMatches[0]) % 2 != 0) { NarroLogger::LogWarn(sprintf('Warning! The translated text "%s" has unclosed double quotes.', $strSuggestionValue)); continue; } fwrite($hndTranslatedFile, join("\t", $arrColumn)); fwrite($hndTranslatedFile, join("\t", $arrTranslatedColumn)); } fclose($hndTranslatedFile); if (filesize($strTranslatedFile) == 0) { unlink($strTranslatedFile); } else { chmod($strTranslatedFile, 0666); } }
if (isset($objProject) && $objProject instanceof NarroProject) { $objCondition = QQ::AndCondition(QQ::Equal(QQN::NarroContextInfo()->LanguageId, QApplication::GetLanguageId()), QQ::Equal(QQN::NarroContextInfo()->Context->ProjectId, $objProject->ProjectId)); } else { $objCondition = QQ::Equal(QQN::NarroContextInfo()->LanguageId, QApplication::GetLanguageId()); } foreach (NarroContextInfo::QueryArray($objCondition, array(QQ::OrderBy(QQN::NarroContextInfo()->Modified, 0), QQ::LimitInfo(20, 0))) as $intKey => $objNarroContextInfo) { $strContextLink = sprintf(__HTTP_URL__ . __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__ . '/' . NarroLink::Translate($objNarroContextInfo->Context->ProjectId, '', 0, '', 0, 0, 10, 0, $objNarroContextInfo->ContextInfoId)); $strProjectLink = sprintf(__HTTP_URL__ . __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__ . '/' . NarroLink::ProjectTextList($objNarroContextInfo->Context->ProjectId, NarroTranslatePanel::SHOW_ALL, '')); $strUserLink = __HTTP_URL__ . __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__ . '/' . NarroLink::UserProfile($objNarroContextInfo->ValidatorUserId); if (isset($objProject) && $objProject instanceof NarroProject) { $strItemName = ''; } else { $strItemName = $objNarroContextInfo->Context->Project->ProjectName . ' :: '; } $objItem = new QRssItem($strItemName . (strlen($objNarroContextInfo->Context->Text->TextValue) > 124 ? substr($objNarroContextInfo->Context->Text->TextValue, 0, 124) . '...' : $objNarroContextInfo->Context->Text->TextValue), $strContextLink); $objItem->Description = sprintf('<p>' . t('Project') . ': <a href="%s">%s</a></p>', $strProjectLink, $objNarroContextInfo->Context->Project->ProjectName) . sprintf('<p>' . t('Context') . ': <a href="%s">%s</a></p>', $strContextLink, NarroString::HtmlEntities($objNarroContextInfo->Context->Context)) . sprintf('<p>' . t('Original text') . ': %s</p>', $objNarroContextInfo->Context->TextAccessKey ? NarroString::Replace($objNarroContextInfo->Context->TextAccessKey, '<u>' . $objNarroContextInfo->Context->TextAccessKey . '</u>', NarroString::HtmlEntities($objNarroContextInfo->Context->Text->TextValue), 1) : NarroString::HtmlEntities($objNarroContextInfo->Context->Text->TextValue)) . ($objNarroContextInfo->ValidSuggestionId ? sprintf('<p>' . t('Approved suggestion') . ': %s</p>', $objNarroContextInfo->Context->TextAccessKey ? NarroString::Replace($objNarroContextInfo->SuggestionAccessKey, '<u>' . $objNarroContextInfo->SuggestionAccessKey . '</u>', NarroString::HtmlEntities($objNarroContextInfo->ValidSuggestion->SuggestionValue), 1) : NarroString::HtmlEntities($objNarroContextInfo->ValidSuggestion->SuggestionValue)) : '') . ($objNarroContextInfo->HasSuggestions ? sprintf(t('The text has %s suggestions'), NarroSuggestion::QueryCount(QQ::AndCondition(QQ::Equal(QQN::NarroSuggestion()->TextId, $objNarroContextInfo->Context->TextId), QQ::Equal(QQN::NarroSuggestion()->LanguageId, QApplication::GetLanguageId())))) : t('The text has no suggestions')) . ($objNarroContextInfo->ValidSuggestionId && $objNarroContextInfo->ValidatorUserId != NarroUser::ANONYMOUS_USER_ID ? sprintf('<p>' . t('Approved by') . ': <a href="%s">%s</a>', $strUserLink, $objNarroContextInfo->ValidSuggestionId ? $objNarroContextInfo->ValidatorUser->RealName : '') : ''); $objItem->PubDate = new QDateTime($objNarroContextInfo->Modified); $objItem->Author = $objNarroContextInfo->ValidSuggestionId ? $objNarroContextInfo->ValidatorUser->RealName : ''; $objRssFeed->AddItem($objItem); $strDescription = ''; } $objRssFeed->Language = strtolower(QApplication::$TargetLanguage->LanguageCode); $objRssFeed->Image = new QRssImage(__HTTP_URL__ . __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__ . '/assets/images/narro.png', t('Narro - Translate, we\'re open!'), __HTTP_URL__ . __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__ . '/index.php'); QApplication::$Cache->save($objRssFeed, $strCacheId, array(), 3600); } $objRssFeed->Run(); break; case 'textcomment': if (isset($objProject) && $objProject instanceof NarroProject) { $strCacheId = sprintf('rssfeed_textcomment_%d_%d', $objProject->ProjectId, QApplication::QueryString('l')); } else {