79 'exportedPhraseCount',
80 'collectUntranslated',
87 'exportedSamplesCount',
95 'collectUntranslated',
104 foreach ($fields as $key)
108 if ($key ==
'filter')
121 self::$useTranslationRepository = Main\Localization\Translation::useTranslationRepository();
122 if (self::$useTranslationRepository)
124 self::$translationRepositoryLanguages = Translate\Config::getTranslationRepositoryLanguages();
127 if (in_array(
'all', $this->languages) || empty($this->languages))
129 $this->languages = Translate\Config::getEnabledLanguages();
142 protected function createExportTempFile(
string $exportFileName): Translate\
IO\CsvFile
145 $exportFolder = Translate\Config::getExportFolder();
146 if (!empty($exportFolder))
149 if ($tempDir->isExists())
155 \preg_match(
"#.+_([0-9]+)\.csv$#", $entry->getName(), $matches) &&
156 (\time() - (
int)$matches[1] > 3 * 3600)
165 $fileName = \preg_replace(
"#(.+)\.csv$#",
"$1_".\time().
'.csv',
$exportFileName);
171 $csvFile = Translate\IO\CsvFile::generateTemporalFile(
'translate',
'.csv', 3);
176 $csvFile->openWrite();
178 $row = [
'file',
'key'];
179 foreach ($this->languages as $langId)
199 ->setRowDelimiter(Translate\
IO\CsvFile::LINE_DELIMITER_WIN)
200 ->prefaceWithUtf8Bom($this->encodingOut ===
'utf-8')
203 switch (Translate\Config::getOption(Translate\Config::OPTION_EXPORT_CSV_DELIMITER))
206 $csvFile->setFieldDelimiter(Translate\
IO\CsvFile::DELIMITER_TAB);
209 $csvFile->setFieldDelimiter(Translate\
IO\CsvFile::DELIMITER_ZPT);
213 $csvFile->setFieldDelimiter(Translate\
IO\CsvFile::DELIMITER_TZP);
227 return \trim(\str_replace([
'.php',
'/'], [
'',
'_'], $path),
'_').
'_'.\implode(
'_',
$languages).
'.csv';
271 string $langFilePath,
272 array $fullLangFilePaths,
274 array $filterByCodeList = []
280 foreach ($this->languages as $langId)
282 $rowLang0[$langId] =
'';
285 $filterByCode = !empty($filterByCodeList);
287 foreach ($this->languages as $langId)
289 if (empty($fullLangFilePaths[$langId]))
294 $fullPath = $fullLangFilePaths[$langId];
296 $file->setLangId($langId);
298 if ($this->convertEncoding)
300 $file->setOperatingEncoding($this->encodingOut);
307 if (!$file->loadTokens())
315 foreach ($file as $code => $phrase)
319 if (!\in_array($code, $filterByCodeList))
324 if (!isset($mergedContent[$code]))
326 $mergedContent[$code] = \array_merge([
'file' => $langFilePath,
'key' => $code], $rowLang0);
328 $mergedContent[$code][$langId] = $phrase;
335 $hasObligatorySetting =
false;
338 if ($settingsFile->load())
340 $langSettings = $settingsFile->getOptions($langFilePath);
345 foreach ($mergedContent as $code => $row)
347 foreach ($row as $langId => $phr)
349 if ($langId ==
'file' || $langId ==
'key')
353 $isObligatory =
true;
354 if ($hasObligatorySetting)
358 if (empty($phr) && ($phr !==
'0') && $isObligatory)
363 unset($mergedContent[$code]);
367 return $mergedContent;
383 foreach ($this->languages as $langId)
385 $langFolderRelPath = Translate\IO\Path::replaceLangId($langPath, $langId);
386 $langFolderFullPath = Translate\IO\Path::tidy(self::$documentRoot.
'/'.$langFolderRelPath);
388 if (self::$useTranslationRepository && \in_array($langId, self::$translationRepositoryLanguages))
390 $langFolderFullPath = Main\Localization\Translation::convertLangPath($langFolderFullPath, $langId);
393 $childrenList = Translate\IO\FileSystemHelper::getFileList($langFolderFullPath);
394 if (!empty($childrenList))
396 foreach ($childrenList as $fullPath)
398 $name = \basename($fullPath);
399 if (\in_array(
$name, Translate\IGNORE_FS_NAMES))
404 if (Translate\
IO\Path::isPhpFile($fullPath,
true))
406 $files[$langPath.
'/'.
$name][$langId] = $fullPath;
412 $childrenList = Translate\IO\FileSystemHelper::getFolderList($langFolderFullPath);
413 if (!empty($childrenList))
415 $ignoreDev = \implode(
'|', Translate\IGNORE_MODULE_NAMES);
416 foreach ($childrenList as $fullPath)
418 $name = \basename($fullPath);
419 if (\in_array(
$name, Translate\IGNORE_FS_NAMES))
424 $relPath = $langFolderRelPath.
'/'.
$name;
426 if (!\is_dir($fullPath))
431 if (\in_array($relPath, Translate\IGNORE_BX_NAMES))
437 if (\preg_match(
"#^bitrix/modules/[^/]+/({$ignoreDev})$#", \trim($relPath,
'/')))
442 if (\in_array(
$name, Translate\IGNORE_LANG_NAMES))
447 $folders[$langPath.
'/'.
$name] = $langPath.
'/'.
$name;
452 if (\count($files) > 0)
457 if (\count($folders) > 0)
459 foreach ($folders as $subFolderPath)
479 public function findSamples(
string $searchPhrase,
string $searchLangId, $stripPath,
int $limit = 50, array $restrictByPathId = []): array
482 'PATH_ID' =>
'PATH_ID',
483 'PHRASE_CODE' =>
'CODE',
484 'FILE_PATH' =>
'PATH.PATH',
491 $minLengthFulltextWorld = Index\PhraseIndexSearch::getFullTextMinLength();
492 $fulltextIndexSearchStr = Index\PhraseIndexSearch::prepareTextForFulltextSearch($searchPhrase);
493 if (\mb_strlen($fulltextIndexSearchStr) > $minLengthFulltextWorld)
495 $phraseFilter[
'*=PHRASE'] = $fulltextIndexSearchStr;
499 $phraseFilter[
'=PHRASE'] = $searchPhrase;
500 if (is_numeric($stripPath))
502 $phraseFilter[
'!=PATH_ID'] = $stripPath;
506 $phraseFilter[
'!=PATH.PATH'] = $stripPath;
509 if (!empty($restrictByPathId))
511 $phraseFilter[
'=PATH.DESCENDANTS.PARENT_ID'] = $restrictByPathId;
514 $ftsClass = Index\Internals\PhraseFts::getFtsEntityClass($searchLangId);
517 $phraseInxRes = $ftsClass::getList([
518 'filter' => $phraseFilter,
525 while ($phraseInx = $phraseInxRes->fetch())
527 $pathId = (int)$phraseInx[
'PATH_ID'];
528 $phraseCode = $phraseInx[
'PHRASE_CODE'];
530 if (!isset($fileInxCache[$pathId]))
533 $fileInxCache[$pathId] = $this->
mergeLangFiles($phraseInx[
'FILE_PATH'], $fullPaths);
537 isset($fileInxCache[$pathId][$phraseCode])
538 && $fileInxCache[$pathId][$phraseCode][$searchLangId] == $searchPhrase
541 $samples[] = $fileInxCache[$pathId][$phraseCode];
555 if (!isset($this->fullPathCache[$pathId]))
557 $this->fullPathCache[$pathId] = [];
558 $fileInxRes = Translate\Index\Internals\FileIndexTable::getList([
559 'filter' => [
'=PATH_ID' => $pathId],
560 'order' => [
'ID' =>
'ASC'],
561 'select' => [
'LANG_ID',
'FULL_PATH'],
563 while ($fileInx = $fileInxRes->fetch())
565 $this->fullPathCache[$pathId][$fileInx[
'LANG_ID']] = $fileInx[
'FULL_PATH'];
569 return $this->fullPathCache[$pathId];
static loadLanguageFile($file, $language=null, $normalize=true)
static getSourceEncoding($lang)