public function ExportFile($strTemplate, $strTranslatedFile)
 {
     $hndExportFile = fopen($strTranslatedFile, 'w');
     if (!$hndExportFile) {
         NarroLogger::LogError(sprintf('Cannot create or write to "%s".', $strTranslatedFile));
         return false;
     }
     if ($this->objProject->GetPreferenceValueByName('Export translators and reviewers in the file header as a comment') == 'Yes') {
         $arrUsers = array();
         foreach ($this->objFile->GetTranslatorArray($this->objTargetLanguage->LanguageId) as $objUser) {
             $arrUsers[] = sprintf("# %s <%s>", $objUser->RealName, $objUser->Email);
         }
         if (count($arrUsers)) {
             fwrite($hndExportFile, sprintf("# Translator(s):\n#\n%s\n#\n", join("\n", $arrUsers)));
         }
         $arrUsers = array();
         foreach ($this->objFile->GetReviewerArray($this->objTargetLanguage->LanguageId) as $objUser) {
             $arrUsers[] = sprintf("# %s <%s>", $objUser->RealName, $objUser->Email);
         }
         if (count($arrUsers)) {
             fwrite($hndExportFile, sprintf("# Reviewer(s):\n#\n%s\n#\n", join("\n", $arrUsers)));
         }
     }
     $arrTemplateFile = $this->getFieldGroups($strTemplate);
     $intTotalContexts = count($arrTemplateFile);
     $intCurrentContext = 0;
     foreach ($arrTemplateFile as $strIndex => $arrTemplateFields) {
         $intCurrentContext++;
         NarroProgress::SetProgressPerFile($intCurrentContext / $intTotalContexts * 100, $this->objProject->ProjectId, 'export');
         $this->objCurrentContext = null;
         if (!is_null($arrTemplateFields['MsgId'])) {
             $arrTemplateFields['MsgId'] = str_replace('\\"', '"', $arrTemplateFields['MsgId']);
         }
         if (!is_null($arrTemplateFields['MsgStr'])) {
             $arrTemplateFields['MsgStr'] = str_replace('\\"', '"', $arrTemplateFields['MsgStr']);
         }
         if (!is_null($arrTemplateFields['MsgPluralId'])) {
             $arrTemplateFields['MsgPluralId'] = str_replace('\\"', '"', $arrTemplateFields['MsgPluralId']);
         }
         if (isset($arrTemplateFields['MsgPluralId'])) {
             for ($intPluralId = 0; $intPluralId < $this->objTargetLanguage->Plurals; $intPluralId++) {
                 $arrTemplateFields['MsgStr' . $intPluralId] = str_replace('\\"', '"', $arrTemplateFields['MsgStr' . $intPluralId]);
             }
         }
         /**
          * if it's not a plural, just add msgid and msgstr
          */
         if (is_null($arrTemplateFields['MsgPluralId'])) {
             /**
              * Leave the header alone
              */
             if ($arrTemplateFields['MsgId'] == '' && strstr($arrTemplateFields['MsgStr'], 'Project-Id-Version')) {
                 /**
                  * This is the header
                  */
                 /**
                  * unset the flag, if is set
                  */
                 unset($arrTemplateFields['Flag']);
                 /**
                  * At import, we concatenate strings on more than one lines, so now we have to restore it
                  */
                 $arrTemplateFields['MsgStr'] = str_replace('\\n', '\\n"' . "\n" . '"', $arrTemplateFields['MsgStr']);
                 /**
                  * There's an extra " at the end, remove it
                  */
                 $arrTemplateFields['MsgStr'] = trim(preg_replace('/"$/', '', $arrTemplateFields['MsgStr']));
                 if (strstr($arrTemplateFields['MsgStr'], '"Plural-Forms')) {
                     /**
                      * the plural declaration is there, try to replace it
                      */
                     $arrTemplateFields['MsgStr'] = preg_replace('/"Plural-Forms:[^"]+"/mi', $this->objTargetLanguage->PluralForm, $arrTemplateFields['MsgStr']);
                 } else {
                     /**
                      * the plural declaration isn't there, try to change it
                      */
                     $arrTemplateFields['MsgStr'] .= "\n" . $this->objTargetLanguage->PluralForm;
                 }
                 /**
                  * There's an extra " at the end, remove it
                  */
                 $arrTemplateFields['MsgStr'] = trim(preg_replace('/"$/', '', $arrTemplateFields['MsgStr']));
                 $strGeneratorLine = sprintf('X-Generator: Narro %s on %s\\n', NARRO_VERSION, __HTTP_URL__ . __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__);
                 if (strstr($arrTemplateFields['MsgStr'], '"X-Generator:')) {
                     $arrTemplateFields['MsgStr'] = $strGeneratorLine;
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strGeneratorLine;
                 }
                 $strProjectLine = sprintf('Project-Id-Version: %s\\n', $this->objProject->ProjectName);
                 if (strstr($arrTemplateFields['MsgStr'], 'Project-Id-Version:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/Project\\-Id\\-Version:[^"]+/mi', $strProjectLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strProjectLine;
                 }
                 $strCharsetLine = sprintf('Content-Type: text/plain; charset=%s\\n', $this->objTargetLanguage->Encoding);
                 if (strstr($arrTemplateFields['MsgStr'], '"Content-Type:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/Content\\-Type:[^"]+/mi', $strCharsetLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strCharsetLine;
                 }
                 $strTranslatorLine = sprintf('Last-Translator: %s <%s>\\n', QApplication::$User->RealName, QApplication::$User->Email);
                 if (strstr($arrTemplateFields['MsgStr'], '"Last-Translator:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/Last\\-Translator:[^"]+/mi', $strTranslatorLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strTranslatorLine;
                 }
                 $strLanguageLine = sprintf('Language-Team: %s <*****@*****.**>\\n', $this->objTargetLanguage->LanguageName);
                 if (strstr($arrTemplateFields['MsgStr'], '"Language-Team:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/Language\\-Team:[^"]+/mi', $strLanguageLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strLanguageLine;
                 }
                 $strRevisionLine = sprintf('PO-Revision-Date: %s\\n', date('Y-m-d H:iO'));
                 if (strstr($arrTemplateFields['MsgStr'], '"PO-Revision-Date:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/PO\\-Revision\\-Date:[^"]+/mi', $strRevisionLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strRevisionLine;
                 }
                 if (!strstr($arrTemplateFields['MsgStr'], '"MIME-Version')) {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"MIME-Version: 1.0\\n';
                 }
                 if (!strstr($arrTemplateFields['MsgStr'], '"Content-Type')) {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"Content-Type: text/plain; charset=UTF-8\\n';
                 }
                 if (!strstr($arrTemplateFields['MsgStr'], '"Content-Transfer-Encoding')) {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"Content-Transfer-Encoding: 8bit\\n';
                 }
                 if (!strstr($arrTemplateFields['MsgStr'], '"Plural-Forms')) {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . $this->objTargetLanguage->PluralForm . "\n" . '"';
                 }
             } else {
                 $arrTemplateFields['MsgStr'] = $this->GetTranslation($this->stripAccessKey($arrTemplateFields['MsgId']), $this->getAccessKey($arrTemplateFields['MsgId']), $this->getAccessKeyPrefix($arrTemplateFields['MsgId']), null, null, $arrTemplateFields['Context']);
             }
         } else {
             /**
              * if it's a plural, add the pluralid with all the msgstr's available
              * the first one is added with msgid/msgstr[0] (this is the singular)
              * the next ones are added with plural id, so in fact they will be tied to the same text
              */
             $strSingularText = $arrTemplateFields['MsgId'];
             if (!is_null($arrTemplateFields['MsgStr0'])) {
                 $arrTemplateFields['MsgStr0'] = $this->GetTranslation($this->stripAccessKey($arrTemplateFields['MsgId']), $this->getAccessKey($arrTemplateFields['MsgId']), $this->getAccessKeyPrefix($arrTemplateFields['MsgId']), null, null, $arrTemplateFields['Context'] . "\nThis text has plurals.");
             }
             for ($intPluralId = 1; $intPluralId < $this->objTargetLanguage->Plurals; $intPluralId++) {
                 $arrTemplateFields['MsgStr' . $intPluralId] = $this->GetTranslation($this->stripAccessKey($arrTemplateFields['MsgPluralId']), $this->getAccessKey($arrTemplateFields['MsgPluralId']), $this->getAccessKeyPrefix($arrTemplateFields['MsgPluralId']), null, null, $arrTemplateFields['Context'] . "\nThis is plural form {$intPluralId} for the text \"" . $strSingularText . "\".");
             }
         }
         if (isset($arrTemplateFields['TranslatorComment']) && !is_null($arrTemplateFields['TranslatorComment'])) {
             fputs($hndExportFile, $arrTemplateFields['TranslatorComment']);
         }
         if (isset($arrTemplateFields['ExtractedComment']) && !is_null($arrTemplateFields['ExtractedComment'])) {
             fputs($hndExportFile, $arrTemplateFields['ExtractedComment']);
         }
         if (isset($arrTemplateFields['Reference']) && !is_null($arrTemplateFields['Reference'])) {
             fputs($hndExportFile, $arrTemplateFields['Reference']);
         }
         if (isset($arrTemplateFields['Flag']) && !is_null($arrTemplateFields['Flag'])) {
             fputs($hndExportFile, $arrTemplateFields['Flag']);
         }
         if (isset($arrTemplateFields['PreviousContext']) && !is_null($arrTemplateFields['PreviousContext'])) {
             fputs($hndExportFile, $arrTemplateFields['PreviousContext']);
         }
         if (isset($arrTemplateFields['PreviousUntranslated']) && !is_null($arrTemplateFields['PreviousUntranslated'])) {
             fputs($hndExportFile, $arrTemplateFields['PreviousUntranslated']);
         }
         if (isset($arrTemplateFields['PreviousUntranslatedPlural']) && !is_null($arrTemplateFields['PreviousUntranslatedPlural'])) {
             fputs($hndExportFile, $arrTemplateFields['PreviousUntranslatedPlural']);
         }
         if (isset($arrTemplateFields['MsgContext']) && !is_null($arrTemplateFields['MsgContext'])) {
             fputs($hndExportFile, sprintf('msgctxt "%s"' . "\n", str_replace('"', '\\"', $arrTemplateFields['MsgContext'])));
         }
         if (isset($arrTemplateFields['MsgId']) && !is_null($arrTemplateFields['MsgId'])) {
             /**
              * If we're exporting a translation that is not approved, mark it as fuzzy
              */
             if ($this->objCurrentContext instanceof NarroContextInfo && !$this->objCurrentContext->ValidSuggestionId && isset($arrTemplateFields['MsgStr']) && $arrTemplateFields['MsgStr'] != '') {
                 NarroImportStatistics::$arrStatistics['Texts exported as fuzzy because they are not approved']++;
                 fputs($hndExportFile, "#, fuzzy\n");
             }
             fputs($hndExportFile, sprintf('msgid "%s"' . "\n", str_replace('"', '\\"', $arrTemplateFields['MsgId'])));
         }
         if (isset($arrTemplateFields['MsgPluralId']) && !is_null($arrTemplateFields['MsgPluralId'])) {
             fputs($hndExportFile, sprintf('msgid_plural "%s"' . "\n", str_replace('"', '\\"', $arrTemplateFields['MsgPluralId'])));
         }
         if (!is_null($arrTemplateFields['MsgStr'])) {
             /**
              * put the header as it is
              */
             if ($arrTemplateFields['MsgId'] == '' && strstr($arrTemplateFields['MsgStr'], 'Project-Id-Version')) {
                 fputs($hndExportFile, sprintf('msgstr "%s"' . "\n", $arrTemplateFields['MsgStr']));
             } else {
                 fputs($hndExportFile, sprintf('msgstr "%s"' . "\n", str_replace(array('"', "\n"), array('\\"', '"' . "\n" . '"'), $arrTemplateFields['MsgStr'])));
             }
         }
         for ($intPluralId = 0; $intPluralId < $this->objTargetLanguage->Plurals; $intPluralId++) {
             if (!is_null($arrTemplateFields['MsgStr' . $intPluralId])) {
                 fputs($hndExportFile, sprintf('msgstr[%d] "%s"' . "\n", $intPluralId, str_replace(array('"', "\n"), array('\\"', '"' . "\n" . '"'), $arrTemplateFields['MsgStr' . $intPluralId])));
             }
         }
         fputs($hndExportFile, "\n");
     }
     fclose($hndExportFile);
     @chmod($strTranslatedFile, 0666);
     /**
      * Try to format the file
      * @todo add php replacement for msgcat
      */
     if (file_exists($strTranslatedFile . '~')) {
         unlink($strTranslatedFile . '~');
     }
     NarroUtils::Exec(sprintf('msgcat %s -w 80 -o %s~', escapeshellarg($strTranslatedFile), escapeshellarg($strTranslatedFile)), $arrOutput, $arrError, $intRetVal, false, null, __TMP_PATH__, true);
     if (file_exists($strTranslatedFile . '~')) {
         unlink($strTranslatedFile);
         copy($strTranslatedFile . '~', $strTranslatedFile);
     }
     if (file_exists($strTranslatedFile . '~')) {
         unlink($strTranslatedFile . '~');
     }
     NarroUtils::Exec(sprintf('msgfmt -cv "%s"', $strTranslatedFile), $arrOutput, $arrError, $intRetVal);
     if ($intRetVal != 0) {
         NarroLogger::LogError(sprintf('Not exporting %s because it has errors: %s', $this->objFile->FilePath, join("\n", $arrOutput)));
         unlink($strTranslatedFile);
     } else {
         @chmod($strTranslatedFile, 0666);
     }
 }
 public function ExportFile($strTemplate, $strTranslatedFile)
 {
     $hndExportFile = fopen($strTranslatedFile, 'w');
     if (!$hndExportFile) {
         NarroLogger::LogWarn(sprintf('Cannot create or write to "%s".', $strTranslatedFile));
         return false;
     }
     $arrTemplateFile = $this->getFieldGroups($strTemplate);
     foreach ($arrTemplateFile as $strContext => $arrTemplateFields) {
         if (!is_null($arrTemplateFields['MsgId'])) {
             $arrTemplateFields['MsgId'] = str_replace('\\"', '"', $arrTemplateFields['MsgId']);
         }
         if (!is_null($arrTemplateFields['MsgStr'])) {
             $arrTemplateFields['MsgStr'] = str_replace('\\"', '"', $arrTemplateFields['MsgStr']);
         }
         if (!is_null($arrTemplateFields['MsgPluralId'])) {
             $arrTemplateFields['MsgPluralId'] = str_replace('\\"', '"', $arrTemplateFields['MsgPluralId']);
         }
         if (isset($arrTemplateFields['MsgPluralId'])) {
             for ($intPluralId = 0; $intPluralId < $this->objTargetLanguage->Plurals; $intPluralId++) {
                 $arrTemplateFields['MsgStr' . $intPluralId] = str_replace('\\"', '"', $arrTemplateFields['MsgStr' . $intPluralId]);
             }
         }
         /**
          * if it's not a plural, just add msgid and msgstr
          */
         if (is_null($arrTemplateFields['MsgPluralId'])) {
             /**
              * Leave the header alone
              */
             if ($arrTemplateFields['MsgId'] == '' && strstr($arrTemplateFields['MsgStr'], 'Project-Id-Version')) {
                 /**
                  * This is the header
                  */
                 /**
                  * unset the flag, if is set
                  */
                 unset($arrTemplateFields['Flag']);
                 /**
                  * At import, we concatenate strings on more than one lines, so no we have to restore it
                  */
                 $arrTemplateFields['MsgStr'] = str_replace('\\n', '\\n"' . "\n" . '"', $arrTemplateFields['MsgStr']);
                 /**
                  * There's an extra " at the end, remove it
                  */
                 $arrTemplateFields['MsgStr'] = trim(preg_replace('/"$/', '', $arrTemplateFields['MsgStr']));
                 if (strstr($arrTemplateFields['MsgStr'], '"Plural-Forms')) {
                     /**
                      * the plural declaration is there, try to replace it
                      */
                     $arrTemplateFields['MsgStr'] = preg_replace('/"Plural-Forms:[^"]+"/mi', $this->objTargetLanguage->PluralForm, $arrTemplateFields['MsgStr']);
                 } else {
                     /**
                      * the plural declaration isn't there, try to change it
                      */
                     $arrTemplateFields['MsgStr'] .= "\n" . $this->objTargetLanguage->PluralForm;
                 }
                 /**
                  * There's an extra " at the end, remove it
                  */
                 $arrTemplateFields['MsgStr'] = trim(preg_replace('/"$/', '', $arrTemplateFields['MsgStr']));
                 $strGeneratorLine = sprintf('X-Generator: Narro %s on %s\\n', NARRO_VERSION, __HTTP_URL__ . __VIRTUAL_DIRECTORY__ . __SUBDIRECTORY__);
                 if (strstr($arrTemplateFields['MsgStr'], '"X-Generator:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/X\\-Generator:[^"]+/mi', $strGeneratorLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strGeneratorLine;
                 }
                 $strProjectLine = sprintf('Project-Id-Version: %s\\n', $this->objProject->ProjectName);
                 if (strstr($arrTemplateFields['MsgStr'], 'Project-Id-Version:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/Project\\-Id\\-Version:[^"]+/mi', $strProjectLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strProjectLine;
                 }
                 $strCharsetLine = sprintf('Content-Type: text/plain; charset=%s\\n', $this->objTargetLanguage->Encoding);
                 if (strstr($arrTemplateFields['MsgStr'], '"Content-Type:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/Content\\-Type:[^"]+/mi', $strCharsetLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strCharsetLine;
                 }
                 $strTranslatorLine = sprintf('Last-Translator: %s <%s>\\n', QApplication::$User->RealName, QApplication::$User->Email);
                 if (strstr($arrTemplateFields['MsgStr'], '"Last-Translator:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/Last\\-Translator:[^"]+/mi', $strTranslatorLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strTranslatorLine;
                 }
                 $strLanguageLine = sprintf('Language-Team: %s <*****@*****.**>\\n', $this->objTargetLanguage->LanguageName);
                 if (strstr($arrTemplateFields['MsgStr'], '"Language-Team:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/Language\\-Team:[^"]+/mi', $strLanguageLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strLanguageLine;
                 }
                 $strRevisionLine = sprintf('PO-Revision-Date: %s\\n', date('Y-m-d H:iO'));
                 if (strstr($arrTemplateFields['MsgStr'], '"PO-Revision-Date:')) {
                     $arrTemplateFields['MsgStr'] = preg_replace('/PO\\-Revision\\-Date:[^"]+/mi', $strRevisionLine, $arrTemplateFields['MsgStr']);
                 } else {
                     $arrTemplateFields['MsgStr'] .= '"' . "\n" . '"' . $strRevisionLine;
                 }
             } else {
                 $arrTemplateFields['MsgStr'] = $this->GetTranslation($this->stripAccessKey($arrTemplateFields['MsgStr']), $this->getAccessKey($arrTemplateFields['MsgStr']), $this->getAccessKeyPrefix($arrTemplateFields['MsgStr']), null, null, $arrTemplateFields['Context']);
             }
         } else {
             /**
              * if it's a plural, add the pluralid with all the msgstr's available
              * the first one is added with msgid/msgstr[0] (this is the singular)
              * the next ones are added with plural id, so in fact they will be tied to the same text
              */
             $strSingularText = $arrTemplateFields['MsgStr0'];
             if (!is_null($arrTemplateFields['MsgStr0'])) {
                 $arrTemplateFields['MsgStr0'] = $this->GetTranslation($this->stripAccessKey($arrTemplateFields['MsgStr0']), $this->getAccessKey($arrTemplateFields['MsgStr0']), $this->getAccessKeyPrefix($arrTemplateFields['MsgStr0']), null, null, $arrTemplateFields['Context'] . "\nThis text has plurals.");
             }
             $strPluralText = $arrTemplateFields['MsgStr1'];
             for ($intPluralId = 1; $intPluralId < $this->objTargetLanguage->Plurals; $intPluralId++) {
                 $arrTemplateFields['MsgStr' . $intPluralId] = $this->GetTranslation($this->stripAccessKey($strPluralText), $this->getAccessKey($strPluralText), $this->getAccessKeyPrefix($strPluralText), null, null, $arrTemplateFields['Context'] . "\nThis is plural form {$intPluralId} for the text \"" . $strSingularText . "\".");
             }
         }
         if (!is_null($arrTemplateFields['TranslatorComment'])) {
             fputs($hndExportFile, $arrTemplateFields['TranslatorComment']);
         }
         if (!is_null($arrTemplateFields['ExtractedComment'])) {
             fputs($hndExportFile, $arrTemplateFields['ExtractedComment']);
         }
         if (!is_null($arrTemplateFields['Reference'])) {
             fputs($hndExportFile, $arrTemplateFields['Reference']);
         }
         if (!is_null($arrTemplateFields['Flag'])) {
             fputs($hndExportFile, $arrTemplateFields['Flag']);
         }
         if (!is_null($arrTemplateFields['PreviousContext'])) {
             fputs($hndExportFile, $arrTemplateFields['PreviousContext']);
         }
         if (!is_null($arrTemplateFields['PreviousUntranslated'])) {
             fputs($hndExportFile, $arrTemplateFields['PreviousUntranslated']);
         }
         if (!is_null($arrTemplateFields['PreviousUntranslatedPlural'])) {
             fputs($hndExportFile, $arrTemplateFields['PreviousUntranslatedPlural']);
         }
         if (!is_null($arrTemplateFields['MsgContext'])) {
             fputs($hndExportFile, sprintf('msgctxt "%s"' . "\n", str_replace('"', '\\"', $arrTemplateFields['MsgContext'])));
         }
         if (!is_null($arrTemplateFields['MsgId'])) {
             fputs($hndExportFile, sprintf('msgid "%s"' . "\n", str_replace('"', '\\"', $arrTemplateFields['MsgId'])));
         }
         if (!is_null($arrTemplateFields['MsgPluralId'])) {
             fputs($hndExportFile, sprintf('msgid_plural "%s"' . "\n", str_replace('"', '\\"', $arrTemplateFields['MsgPluralId'])));
         }
         if (!is_null($arrTemplateFields['MsgStr'])) {
             /**
              * put the header as it is
              */
             if ($arrTemplateFields['MsgId'] == '' && strstr($arrTemplateFields['MsgStr'], 'Project-Id-Version')) {
                 fputs($hndExportFile, sprintf('msgstr "%s"' . "\n", $arrTemplateFields['MsgStr']));
             } else {
                 fputs($hndExportFile, sprintf('msgstr "%s"' . "\n", str_replace(array('"', "\n"), array('\\"', '"' . "\n" . '"'), $arrTemplateFields['MsgStr'])));
             }
         }
         for ($intPluralId = 0; $intPluralId < $this->objTargetLanguage->Plurals; $intPluralId++) {
             if (!is_null($arrTemplateFields['MsgStr' . $intPluralId])) {
                 fputs($hndExportFile, sprintf('msgstr[%d] "%s"' . "\n", $intPluralId, str_replace(array('"', "\n"), array('\\"', '"' . "\n" . '"'), $arrTemplateFields['MsgStr' . $intPluralId])));
             }
         }
         fputs($hndExportFile, "\n");
         if ($arrTemplateFields['MsgId'] == '') {
             fputs($hndExportFile, $strLine);
         }
     }
     fclose($hndExportFile);
     chmod($strTranslatedFile, 0666);
     /**
      * Try to format the file
      * @todo add php replacement for msgcat
      */
     if (file_exists($strTranslatedFile . '~')) {
         unlink($strTranslatedFile . '~');
     }
     NarroUtils::Exec(sprintf('msgcat %s -w 80 -o %s~', escapeshellarg($strTranslatedFile), escapeshellarg($strTranslatedFile)), $arrOutput, $arrError, $intRetVal, false, null, __TMP_PATH__, true);
     if (file_exists($strTranslatedFile . '~')) {
         unlink($strTranslatedFile);
         copy($strTranslatedFile . '~', $strTranslatedFile);
     }
     unlink($strTranslatedFile . '~');
     chmod($strTranslatedFile, 0666);
 }
예제 #3
0
 public function btnTest_Click()
 {
     if ($this->RepositorySetup() == 0) {
         $mixProcess = NarroUtils::Exec(sprintf('svn diff > %s_diff', $this->strSSHKey), $arrOutput, $arrError, $intRetVal, false, array('SVN_SSH' => sprintf('ssh -o StrictHostKeyChecking=no -l %s -p 22 -i %s', escapeshellarg($this->txtUsername->Text), $this->strSSHKey), 'HOME' => __TMP_PATH__), $this->strSSHKey . '_svn', true);
     } else {
         $this->lblOutput->Text = join("\n", $arrOutput);
     }
     $this->Form->RemoveControl($this->pnlPatchViewer->ControlId);
     NarroPatchViewerPanel::$strFileExpression = '/^\\-\\-\\-\\s([^\\(]+).*$/';
     $this->pnlPatchViewer = new NarroPatchViewerPanel($this->strSSHKey . '_diff', $this);
     unlink($this->strSSHKey);
     unlink($this->strSSHKey . '_diff');
     NarroUtils::RecursiveDelete($this->strSSHKey . '_svn');
     $this->btnCommit->Display = true;
 }
예제 #4
0
 public function ExportProject()
 {
     if ($this->objProject->ProjectName == 'Narro') {
         $this->strTemplatePath = __DOCROOT__ . __SUBDIRECTORY__ . '/locale/en-US';
         $this->strTranslationPath = __DOCROOT__ . __SUBDIRECTORY__ . '/locale/' . $this->objTargetLanguage->LanguageCode;
         if (!file_exists($this->strTranslationPath)) {
             mkdir($this->strTranslationPath, 0777);
         }
     }
     NarroLogger::LogInfo(sprintf(t('Starting export for the project %s using as template %s'), $this->objProject->ProjectName, $this->strTemplatePath));
     NarroLogger::LogInfo(sprintf('Active plugins: %s', join(',', QApplication::$PluginHandler->ActivePlugins)));
     NarroLogger::LogInfo(sprintf('Running export under user %s', $this->objUser->Username));
     $this->startTimer();
     QApplication::$PluginHandler->BeforeExportProject($this->objProject);
     if (file_exists($this->strTemplatePath) && is_dir($this->strTemplatePath)) {
         if ($this->ExportFromDirectory()) {
             $this->stopTimer();
             NarroLogger::LogInfo(sprintf('Export finished successfully in %d seconds.', NarroImportStatistics::$arrStatistics['End time'] - NarroImportStatistics::$arrStatistics['Start time']));
         } else {
             NarroLogger::LogError('Export failed.');
         }
     } else {
         throw new Exception(sprintf('Template path "%s" does not exist or it is not a directory', $this->strTemplatePath));
     }
     if (function_exists('popen') && function_exists('escapeshellarg') && function_exists('escapeshellcmd') && file_exists($this->strTemplatePath . '/../export.sh')) {
         NarroLogger::LogInfo('Found an after export script, trying to run it.');
         $fp = popen(sprintf('/bin/sh %s %s %d %s %d %d 2>&1', escapeshellarg(realpath($this->strTemplatePath . '/..') . '/export.sh'), escapeshellarg($this->objTargetLanguage->LanguageCode), $this->objTargetLanguage->LanguageId, escapeshellarg($this->objProject->ProjectName), $this->objProject->ProjectId, QApplication::GetUserId()), 'r');
         $strOutput = '';
         while (!feof($fp)) {
             $strOutput .= fread($fp, 1024);
         }
         if (pclose($fp)) {
             NarroLogger::LogError("After export script failed:\n" . $strOutput);
         } else {
             NarroLogger::LogInfo("After export script finished successfully:\n" . $strOutput);
         }
     }
     if ($this->objProject->ProjectName == 'Narro') {
         NarroUtils::Exec(sprintf('msgfmt -cv %s -o %s 2>&1', escapeshellarg($this->strTranslationPath . '/narro.po'), escapeshellarg($this->strTranslationPath . '/narro.mo')), $arrOutput, $arrError, $intRetVal);
         if ($intRetVal != 0) {
             NarroLogger::LogError("Exporting Narro's translation failed:\n" . $strOutput);
         } else {
             NarroLogger::LogInfo("Exported Narro's translation succesfully. Press Ctrl+F5 to reload and see it.");
         }
         if (file_exists($this->strTranslationPath . '/narro.mo')) {
             chmod($this->strTranslationPath . '/narro.mo', 0666);
         }
     }
     NarroProgress::ClearProgressFileName($this->objProject->ProjectId, 'export');
     QApplication::$PluginHandler->AfterExportProject($this->objProject);
     foreach (NarroImportStatistics::$arrStatistics as $strName => $strValue) {
         if ($strValue != 0) {
             NarroLogger::LogInfo(stripslashes($strName) . ': ' . $strValue);
         }
     }
     if (SERVER_INSTANCE == 'dev') {
         $strQueryData = '';
         $intTimeSpentOnQueries = 0;
         if (isset($GLOBALS['arrQueries']) && is_array($GLOBALS['arrQueries'])) {
             foreach ($GLOBALS['arrQueries'] as $arrQueryData) {
                 $strQueryData .= '"' . join('";"', $arrQueryData) . '"';
                 $intTimeSpentOnQueries += $arrQueryData[1];
             }
         }
         file_put_contents(__TMP_PATH__ . '/queries.csv', $strQueryData);
         chmod(__TMP_PATH__ . '/queries.csv', 0666);
         $strCacheData = '';
         if (isset($GLOBALS['arrCacheQueries']) && is_array($GLOBALS['arrCacheQueries'])) {
             foreach ($GLOBALS['arrCacheQueries'] as $arrCacheData) {
                 $strCacheData .= '"' . join('";"', $arrCacheData) . '"';
             }
         }
         file_put_contents(__TMP_PATH__ . '/cache.csv', $strCacheData);
         chmod(__TMP_PATH__ . '/cache.csv', 0666);
         NarroLogger::LogInfo(sprintf('%d queries in total, %d seconds spent on them', count(@$GLOBALS['arrQueries']), $intTimeSpentOnQueries));
         NarroLogger::LogInfo(sprintf('%d cache queries in total, %s seconds spent on them', count(@$GLOBALS['arrCacheQueries']), intval(@$GLOBALS['arrCacheQueriesSpent'])));
     }
 }
 public function btnImport_Click($strFormId, $strControlId, $strParameter)
 {
     if (!QApplication::HasPermissionForThisLang('Can import project', $this->objProject->ProjectId)) {
         return false;
     }
     $strProcLogFile = __TMP_PATH__ . '/' . $this->objProject->ProjectId . '-' . QApplication::$TargetLanguage->LanguageCode . '-import-process.log';
     $strProcPidFile = __TMP_PATH__ . '/' . $this->objProject->ProjectId . '-' . QApplication::$TargetLanguage->LanguageCode . '-import-process.pid';
     $strProgressFile = __TMP_PATH__ . '/import-' . $this->objProject->ProjectId . '-' . QApplication::$TargetLanguage->LanguageCode;
     if ($strParameter == 1) {
         if (NarroUtils::IsProcessRunning('import', $this->objProject->ProjectId)) {
             $this->objImportProgress->Translated = NarroProgress::GetProgress($this->objProject->ProjectId, 'import');
             $this->objImportProgress->MarkAsModified();
         } else {
             $this->lblImport->Text = t('Import finished.');
             if (QApplication::$UseAjax) {
                 QApplication::ExecuteJavaScript('if (typeof lastImportId != \'undefined\') clearInterval(lastImportId)');
             }
             if (file_exists($strProcLogFile) && filesize($strProcLogFile)) {
                 NarroLogger::LogInfo(sprintf('There are messages from the background process: %s', file_get_contents($strProcLogFile)));
             }
             if (file_exists($strProcLogFile)) {
                 unlink($strProcLogFile);
             }
             if (file_exists($strProcPidFile)) {
                 unlink($strProcPidFile);
             }
             if (file_exists($strProgressFile)) {
                 unlink($strProgressFile);
             }
             $this->lblImport->Visible = true;
             $this->btnImport->Visible = true;
             $this->btnKillProcess->Visible = false;
             $this->objImportProgress->Translated = 0;
             $this->objImportProgress->Visible = false;
         }
         $this->pnlLogViewer->MarkAsModified();
     } elseif ($strParameter == 2) {
         $this->pnlLogViewer->ProjectId = $this->objProject->ProjectId;
         $this->pnlLogViewer->LanguageId = QApplication::GetLanguageId();
         $this->pnlLogViewer->DateStart = QDateTime::Now();
         NarroProgress::ClearProgressFileName($this->objProject->ProjectId, 'import');
         set_time_limit(0);
         if (file_exists($strProcLogFile)) {
             unlink($strProcLogFile);
         }
         if (file_exists($strProcPidFile)) {
             unlink($strProcPidFile);
         }
         if (file_exists($strProgressFile)) {
             unlink($strProgressFile);
         }
         $objNarroImporter = new NarroProjectImporter();
         /**
          * Get boolean options
          */
         $objNarroImporter->CheckEqual = true;
         $objNarroImporter->Approve = $this->chkApproveImportedTranslations->Checked;
         $objNarroImporter->ApproveAlreadyApproved = !$this->chkApproveOnlyNotApproved->Checked;
         $objNarroImporter->OnlySuggestions = !$this->chkImportSourceTexts->Checked;
         $objNarroImporter->Project = $this->objProject;
         $objNarroImporter->ImportUnchangedFiles = $this->chkImportUnchangedFiles->Checked;
         $objNarroImporter->User = QApplication::$User;
         $objNarroImporter->TargetLanguage = QApplication::$TargetLanguage;
         $objNarroImporter->SourceLanguage = NarroLanguage::LoadByLanguageCode(NarroLanguage::SOURCE_LANGUAGE_CODE);
         try {
             $objNarroImporter->TranslationPath = $this->pnlTranslationsSource->Directory;
             $objNarroImporter->TemplatePath = $this->objProject->DefaultTemplatePath;
         } catch (Exception $objEx) {
             NarroLogger::LogError(sprintf('An error occurred during import: %s', $objEx->getMessage()));
             $this->lblImport->Text = sprintf(t('Import failed: %s'), $objEx->getMessage());
             return false;
         }
         try {
             $objNarroImporter->ImportProject();
         } catch (Exception $objEx) {
             NarroLogger::LogError(sprintf('An error occurred during import: %s', $objEx->getMessage()));
             $this->lblImport->Text = sprintf(t('Import failed: %s'), $objEx->getMessage());
         }
         $this->lblImport->Visible = true;
         $this->btnImport->Visible = true;
         $this->btnKillProcess->Visible = false;
         $this->objImportProgress->Visible = false;
         $this->pnlLogViewer->MarkAsModified();
     } else {
         $this->pnlLogViewer->ProjectId = $this->objProject->ProjectId;
         $this->pnlLogViewer->LanguageId = QApplication::GetLanguageId();
         $this->pnlLogViewer->DateStart = QDateTime::Now();
         NarroProgress::ClearProgressFileName($this->objProject->ProjectId, 'import');
         $this->pnlLogViewer->MarkAsModified();
         $this->btnImport->Visible = false;
         $this->btnKillProcess->Visible = QApplication::HasPermission('Administrator', $this->objProject, QApplication::$TargetLanguage->LanguageCode) && !$this->btnImport->Visible;
         $this->objImportProgress->Visible = true;
         $this->objImportProgress->Translated = 0;
         $this->lblImport->Text = '';
         try {
             $strCommand = sprintf(__PHP_CLI_PATH__ . ' ' . escapeshellarg(sprintf('%s/includes/narro/importer/narro-cli.php', __DOCROOT__ . __SUBDIRECTORY__)) . ' --import --minloglevel 3 --project %d --user %d --check-equal ' . ($this->chkApproveImportedTranslations->Checked ? '--approve ' : '') . ($this->chkImportUnchangedFiles->Checked ? '--import-unchanged-files ' : '') . ($this->chkApproveOnlyNotApproved->Checked ? '' : '--approve-already-approved ') . (!$this->chkImportSourceTexts->Checked || !QApplication::HasPermission('Can import project', $this->objProject->ProjectId) ? '--only-suggestions ' : '') . ' --template-lang %s --translation-lang %s --template-directory %s --translation-directory %s', (int) $this->objProject->ProjectId, (int) QApplication::$User->UserId, escapeshellarg(NarroLanguage::SOURCE_LANGUAGE_CODE), escapeshellarg(QApplication::$TargetLanguage->LanguageCode), escapeshellarg($this->objProject->DefaultTemplatePath), escapeshellarg($this->pnlTranslationsSource->Directory));
         } catch (Exception $objEx) {
             NarroLogger::LogError(sprintf('An error occurred during import: %s', $objEx->getMessage()));
             $this->lblImport->Text = sprintf(t('Import failed: %s'), $objEx->getMessage());
             $this->lblImport->Visible = true;
             $this->btnImport->Visible = true;
             $this->btnKillProcess->Visible = QApplication::HasPermission('Administrator', $this->objProject, QApplication::$TargetLanguage->LanguageCode) && !$this->btnImport->Visible;
             $this->objImportProgress->Translated = 0;
             $this->objImportProgress->Visible = false;
             $this->pnlLogViewer->MarkAsModified();
             return false;
         }
         if (file_exists($strProcLogFile) && is_writable($strProcLogFile)) {
             unlink($strProcLogFile);
         }
         NarroUtils::Exec($strCommand, $arrOutput, $arrError, $intRetVal, true);
         if ($intRetVal == 0) {
             if (QApplication::$UseAjax) {
                 QApplication::ExecuteJavaScript(sprintf('lastImportId = setInterval("qc.pA(\'%s\', \'%s\', \'QClickEvent\', \'1\')", %d);', $strFormId, $strControlId, 2000));
             } else {
                 $this->btnImport_Click($strFormId, $strControlId, 1);
             }
         } else {
             $this->objImportProgress->Visible = false;
             NarroLogger::LogError('Failed to launch a background process, there will be no progress displayed, and it might take a while, please wait for more messages');
             $this->pnlLogViewer->MarkAsModified();
             /**
              * try importing without launching a background process
              */
             if (QApplication::$UseAjax) {
                 QApplication::ExecuteJavaScript(sprintf('lastImportId = setTimeout("qc.pA(\'%s\', \'%s\', \'QClickEvent\', \'2\')", %d);', $strFormId, $strControlId, 2000));
             } else {
                 $this->btnImport_Click($strFormId, $strControlId, 2);
             }
         }
     }
 }