- Модуль: translate
- Путь к файлу: ~/bitrix/modules/translate/lib/controller/editor/savefile.php
- Класс: BitrixTranslateControllerEditorSaveFile
- Вызов: SaveFile::run
public function run($file = '')
{
Loc::loadLanguageFile(__DIR__. '/operation.php');
Loc::loadLanguageFile(__FILE__);
$result = [];
if (empty($file))
{
$this->addError(new MainError(Loc::getMessage('TR_EDIT_FILE_PATH_ERROR')));
return $result;
}
$normalized = MainIOPath::normalize($file);
if ($normalized != $file)
{
$this->addError(new MainError(Loc::getMessage('TR_EDIT_FILE_WRONG_NAME')));
return $result;
}
$file = $normalized;
if (!TranslateIOPath::isLangDir($file, true) || !TranslateIOPath::isPhpFile($file))
{
$this->addError(new MainError(Loc::getMessage('TR_EDIT_ERROR_FILE_NOT_LANG', ['#FILE#' => $file])));
return $result;
}
if (!TranslatePermission::isAllowPath($file))
{
$this->addError(new MainError(Loc::getMessage('TR_EDIT_FILE_WRONG_NAME')));
return $result;
}
$request = $this->controller->getRequest();
$phraseIdsToDrop = $languagesToDrop = $phraseIdsToUpdate = $languagesToUpdate = [];
$enabledLanguagesList = TranslateConfig::getEnabledLanguages();
$currentEncoding = MainLocalizationTranslation::getCurrentEncoding();
$currentLang = Loc::getCurrentLang();
$limitEncoding = !($currentEncoding === 'utf-8' || MainLocalizationTranslation::useTranslationRepository());
$isEncodingCompatible = function ($langId) use ($limitEncoding, $currentEncoding, $currentLang)
{
$compatible = true;
if ($limitEncoding)
{
$compatible = (
$langId == $currentLang ||
TranslateConfig::getCultureEncoding($langId) == $currentEncoding ||
$langId === 'en'
);
}
return $compatible;
};
// codes to drop
$phraseIdsToDropTmp = $request->getPost('DROP');
if ($phraseIdsToDropTmp !== null && is_array($phraseIdsToDropTmp) && count($phraseIdsToDropTmp) > 0)
{
$phraseIdsToDrop = $phraseIdsToDropTmp;
$languagesToDrop = $enabledLanguagesList;
}
unset($phraseIdsToDropTmp);
// codes to update
$phraseIdsToUpdateTmp = $request->getPost('KEYS');
if ($phraseIdsToUpdateTmp !== null && is_array($phraseIdsToUpdateTmp) && count($phraseIdsToUpdateTmp) > 0)
{
$phraseIdsToUpdate = $phraseIdsToUpdateTmp;
}
unset($phraseIdsToUpdateTmp);
// languages to update
$languagesToUpdateTmp = $request->getPost('LANGS');
if ($languagesToUpdateTmp !== null && is_array($languagesToUpdateTmp) && count($languagesToUpdateTmp) > 0)
{
$languagesToUpdate = array_intersect($languagesToUpdateTmp, $enabledLanguagesList);
}
unset($languagesToUpdateTmp);
// check
if (empty($phraseIdsToUpdate) && empty($phraseIdsToDrop))
{
$result['SUMMARY'] = Loc::getMessage('TR_EDIT_SAVING_COMPLETED');
return $result;
}
if (!empty($phraseIdsToUpdate) && empty($languagesToUpdate))
{
$this->addError(new MainError(Loc::getMessage('TR_EDIT_PARAM_ERROR')));
return $result;
}
$documentRoot = rtrim(TranslateIOPath::tidy(MainApplication::getDocumentRoot()), '/');
$result['DROPPED'] = [];
$result['UPDATED'] = [];
$result['CLEANED'] = [];
foreach ($enabledLanguagesList as $langId)
{
if (!in_array($langId, $languagesToUpdate) && !in_array($langId, $languagesToDrop))
{
continue;
}
$langRelPath = TranslateIOPath::replaceLangId($file, $langId);
$fullPath = TranslateIOPath::tidy($documentRoot. '/'. $langRelPath);
$fullPath = MainLocalizationTranslation::convertLangPath($fullPath, $langId);
$langFile = new TranslateFile($fullPath);
$langFile->setLangId($langId);
// update and drop
if (in_array($langId, $languagesToUpdate))
{
$langFile->setOperatingEncoding($currentEncoding);
}
// just drop
elseif (in_array($langId, $languagesToDrop))
{
$langFile->setOperatingEncoding(MainLocalizationTranslation::getSourceEncoding($langId));
}
if (!$langFile->loadTokens())
{
if (!$langFile->load() && $langFile->hasErrors())
{
foreach ($langFile->getErrors() as $error)
{
if ($error->getCode() !== 'EMPTY_CONTENT')
{
$this->addError($error);
}
}
}
}
if (count($this->getErrors()) > 0)
{
continue;
}
$hasDataToUpdate = false;
// drop phrases
if (in_array($langId, $languagesToDrop))
{
foreach ($phraseIdsToDrop as $phraseId)
{
if (isset($langFile[$phraseId]))
{
unset($langFile[$phraseId]);
$hasDataToUpdate = true;
if (!in_array($phraseId, $result['DROPPED']))
{
$result['DROPPED'][] = $phraseId;
}
}
}
}
// set phrases
if (in_array($langId, $languagesToUpdate) && $isEncodingCompatible($langId))
{
foreach ($phraseIdsToUpdate as $phraseId)
{
// has been deleted
if (in_array($phraseId, $phraseIdsToDrop))
{
continue;
}
$fldName = $this->generateFieldName($phraseId, $langId);
if (!isset($request[$fldName]))
{
continue;
}
$inpValue = $request->getPost($fldName);
/** @var ArrayAccess $langFile */
if (!empty($inpValue) || $inpValue === '0')
{
if ($langFile[$phraseId] !== $inpValue)
{
$langFile[$phraseId] = $inpValue;
$hasDataToUpdate = true;
if (!in_array($fldName, $result['UPDATED']))
{
$result['UPDATED'][] = $fldName;
}
}
}
// remove empty
elseif (isset($langFile[$phraseId]) && $inpValue === '')
{
unset($langFile[$phraseId]);
$hasDataToUpdate = true;
if (!in_array($fldName, $result['CLEANED']))
{
$result['CLEANED'][] = $fldName;
}
}
}
}
if ($hasDataToUpdate)
{
if ($langFile->count() > 0)
{
if ($this->updateLangFile($langFile))
{
$langFile->updatePhraseIndex();
}
}
else
{
if ($langFile->isExists())
{
$langFile->deletePhraseIndex();
if ($this->deleteLangFile($langFile))
{
$langFile->removeEmptyParents();
}
}
}
}
}
if (!$this->hasErrors())
{
$result['SUMMARY'] = Loc::getMessage('TR_EDIT_SAVING_COMPLETED');
}
return $result;
}