Current Path : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/modules/translate/lib/ |
Current File : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/modules/translate/lib/componentbase.php |
<?php namespace Bitrix\Translate; use Bitrix\Main; use Bitrix\Main\Error; use Bitrix\Main\Localization; use Bitrix\Main\Localization\Loc; use Bitrix\Translate; abstract class ComponentBase extends \CBitrixComponent implements Translate\IErrorable { use Translate\Error; use Translate\Warning; const STATUS_SUCCESS = 'success'; const STATUS_DENIED = 'denied'; const STATUS_ERROR = 'error'; const TEMPLATE_ERROR = 'error'; /** @var string */ protected $path = ''; /** @var int Session tab counter. */ protected $tabId = 0; /** * @return boolean */ protected function checkModuleAvailability() { if (!Main\Loader::includeModule('translate')) { if ($this->isAjaxRequest()) { $this->sendJsonResponse(new Error('Module "translate" is not installed.', self::STATUS_ERROR)); } else { $this->addError(new Error('Module "translate" is not installed.', self::STATUS_ERROR)); $this->includeComponentTemplate(self::TEMPLATE_ERROR); } return false; } return true; } /** * Checks if user has permission to view language file. * @param \CUser $user User to check permissions. * @return boolean */ protected function hasUserPermissionView($user) { return Translate\Permission::canView($user); } /** * Checks if user has permission to edit language file. * @param \CUser $user User to check permissions. * @return boolean */ protected function hasUserPermissionEdit($user) { return Translate\Permission::canEdit($user); } /** * Checks if user has permission to edit source language file. * @param \CUser $user User to check permissions. * @return boolean */ protected function hasUserPermissionEditSource($user) { return Translate\Permission::canEditSource($user); } /** * Checks if user has permission to view language file. * @return boolean */ protected function checkPermissionView() { if (!$this->hasUserPermissionView($this->getUser())) { if ($this->isAjaxRequest()) { $this->sendJsonResponse(new Error(Loc::getMessage('TRANSLATE_FILTER_ERROR_ACCESS_DENIED'), self::STATUS_DENIED)); } else { $this->addError(new Error(Loc::getMessage('TRANSLATE_FILTER_ERROR_ACCESS_DENIED'), self::STATUS_DENIED)); $this->includeComponentTemplate(self::TEMPLATE_ERROR); } return false; } return true; } /** * Checks if user has permission to edit language file. * @return boolean */ protected function checkPermissionEdit() { if (!$this->hasUserPermissionEdit($this->getUser())) { if ($this->isAjaxRequest()) { $this->sendJsonResponse(new Error(Loc::getMessage('TRANSLATE_FILTER_ERROR_WRITING_RIGHTS'), self::STATUS_DENIED)); } else { $this->addError(new Error(Loc::getMessage('TRANSLATE_FILTER_ERROR_WRITING_RIGHTS'), self::STATUS_DENIED)); $this->includeComponentTemplate(self::TEMPLATE_ERROR); } return false; } return true; } /** * Checks if user has permission to edit source language file. * @return boolean */ protected function checkPermissionEditPhp() { if (!$this->hasUserPermissionEditSource($this->getUser())) { if ($this->isAjaxRequest()) { $this->sendJsonResponse(new Error(Loc::getMessage('TRANSLATE_FILTER_ERROR_PHP_EDIT_RIGHTS'), self::STATUS_DENIED)); } else { $this->addError(new Error(Loc::getMessage('TRANSLATE_FILTER_ERROR_PHP_EDIT_RIGHTS'), self::STATUS_DENIED)); $this->includeComponentTemplate(self::TEMPLATE_ERROR); } return false; } return true; } /** * Checks some mysql config variables. * @return void */ protected function checkModuleStepper(): void { $stepper = \Bitrix\Main\Update\Stepper::getHtml('translate', Loc::getMessage('TRANSLATE_INDEX_STEPPER')); if (!empty($stepper)) { $this->arResult['STEPPER'] = $stepper; } } /** * Checks FTS if tables exists. * @return void */ protected function checkFtsTables(): void { Translate\Index\Internals\PhraseFts::checkTables(); } /** * Checks some mysql config variables. * @return void */ protected function checkMysqlConfig(): void { $majorVersion = (int)\mb_substr(\Bitrix\Main\Application::getConnection()->getVersion()[0], 0, 1); if ($majorVersion >= 8) { $conf = Main\Application::getConnection()->query("SHOW VARIABLES LIKE 'regexp_time_limit'")->fetch(); if ($conf['Variable_name'] == 'regexp_time_limit') { if ((int)$conf['Value'] <= 0) { $this->addWarning(new Error(Loc::getMessage('TRANSLATE_MYSQL_CONFIG_ERROR_REGEXP_TIME_LIMIT'), self::STATUS_ERROR)); } } } } /** * @return void */ protected function prepareParams() { $params =& $this->getParams(); if (empty($params['CURRENT_LANG'])) { $params['CURRENT_LANG'] = Loc::getCurrentLang(); } if (empty($params['LIST_PATH'])) { $params['LIST_PATH'] = '/bitrix/admin/translate_list.php'; } if (empty($params['EDIT_PATH'])) { $params['EDIT_PATH'] = '/bitrix/admin/translate_edit.php'; } if (empty($params['SHOW_SOURCE_PATH'])) { $params['SHOW_SOURCE_PATH'] = '/bitrix/admin/translate_show_php.php'; } if (empty($params['EDIT_SOURCE_PATH'])) { $params['EDIT_SOURCE_PATH'] = '/bitrix/admin/translate_edit_php.php'; } $params['SET_TITLE'] = isset($params['SET_TITLE']) ? $params['SET_TITLE'] === 'Y' : true; $this->arResult['IS_AJAX_REQUEST'] = $this->isAjaxRequest(); $this->arResult['ALLOW_VIEW'] = $this->hasUserPermissionView($this->getUser()); $this->arResult['ALLOW_EDIT'] = $this->hasUserPermissionEdit($this->getUser()); $this->arResult['ALLOW_EDIT_SOURCE'] = $this->hasUserPermissionEditSource($this->getUser()); } /** * Moves current language to the first position. * * @param string[] $languageList * @param string $currentLangId * * @return string[] */ protected function rearrangeLanguages($languageList, $currentLangId) { $inx = \array_search($currentLangId, $languageList, true); if ($inx !== false) { unset($languageList[$inx]); } \array_unshift($languageList, $currentLangId); return $languageList; } /** * @return string[] */ protected function getLanguages() { static $languagesList; if (empty($languagesList)) { $languagesList = Translate\Config::getEnabledLanguages(); } return $languagesList; } /** * Returns list of language names from the site settings. * * @param string[] $languageIds Languages list to get name. * * @return array */ protected function getLanguagesTitle($languageIds) { $titles = Translate\Config::getLanguagesTitle($languageIds); array_walk($titles, function(&$title, $langId) { $title = "{$title} ({$langId})"; }); return $titles; } /** * Return languages compatible by their encoding. * * @return string[] */ protected function getCompatibleLanguages() { static $languages = array(); if (empty($languages)) { $currentEncoding = Localization\Translation::getCurrentEncoding(); $currentLang = Loc::getCurrentLang(); $limitEncoding = !($currentEncoding == 'utf-8' || Localization\Translation::useTranslationRepository()); $isEncodingCompatible = function ($langId) use ($limitEncoding, $currentEncoding, $currentLang) { $compatible = true; if ($limitEncoding) { $compatible = ( $langId == $currentLang || Translate\Config::getCultureEncoding($langId) == $currentEncoding || $langId == 'en' ); } return $compatible; }; $enabledLanguages = $this->getLanguages(); foreach ($enabledLanguages as $langId) { if ($limitEncoding && !$isEncodingCompatible($langId)) { continue; } $languages[] = $langId; } } return $languages; } /** * @return string */ protected function detectTabId() { $tabId = $this->request->get('tabId'); if (!empty($tabId) && (int)$tabId > 0) { $this->tabId = (int)$tabId; } elseif ($this->isAjaxRequest()) { $this->tabId = Translate\Filter::getTabId(false); } else { $this->tabId = Translate\Filter::getTabId(); } return $this->tabId; } /** * @return string */ protected function detectStartingPath(?string $path = ''): string { $home = Translate\Config::getDefaultPath(); $initPaths = Translate\Config::getInitPath(); if (count($initPaths) > 0) { $home = $initPaths[0]; if (!empty($path)) { foreach ($initPaths as $initPath) { if (\mb_strpos($path, $initPath) === 0) { $home = $initPath; break; } } } } return $home; } /** * Returns component calling params by reference. * @return array */ public function &getParams() { return $this->arParams; } /** * Returns component resulting array by reference. * @return array */ public function &getResult() { return $this->arResult; } /** * @return \CUser */ protected function getUser() { /** @global \CUser $USER */ global $USER; return $USER; } /** * @return \CMain */ protected function getApplication() { /** @global \CMain $APPLICATION */ global $APPLICATION; return $APPLICATION; } /** * Returns whether this is an AJAX (XMLHttpRequest) request. * @return boolean */ protected function isAjaxRequest() { return ($this->request->isAjaxRequest() || $this->request->get('AJAX_CALL') !== null) && $this->request->getRequestMethod() == 'POST'; } /** * Sends Json response to client. * * @param array|object|Main\Error $response Response to send. * * @throws Main\ArgumentException * @return void */ protected function sendJsonResponse($response) { $this->getApplication()->restartBuffer(); $answer = Main\Application::getInstance()->getContext()->getResponse(); if ($response instanceof Main\Error) { $this->addError($response); $response = array(); } $response['result'] = true; if ($this->hasErrors()) { $answer->setStatus('500 Internal Server Error'); $response['status'] = self::STATUS_ERROR; $errors = array(); foreach ($this->getErrors() as $error) { /** @var Main\Error $error */ $errors[] = array( 'message' => $error->getMessage(), 'code' => $error->getCode(), ); } $response['result'] = false; $response['errors'] = $errors; } elseif (!isset($response['status'])) { $response['status'] = self::STATUS_SUCCESS; } $answer->addHeader('Content-Type', 'application/x-javascript; charset=UTF-8'); echo Main\Web\Json::encode($response); \CMain::finalActions(); } /** * Drops saved options. * @param string $category Group option name. * @param string $nameMask Option name mask. * @return void */ protected function clearSavedOptions($category, $nameMask) { $res = \CUserOptions::getList(false,['CATEGORY' => $category, 'USER_ID' => $this->getUser()->getId(), 'NAME_MASK' => $nameMask]); while ($opt = $res->fetch()) { \CUserOptions::deleteOption($category, $opt['NAME']); } } /** * Finds way to get back. * * @param string $path Path to analise. * * @return string */ protected function detectPathBack($path) { static $pathBackCache = array();; if (!isset($pathBackCache[$path])) { $pathBack = \dirname($path); $slash = \explode('/', $pathBack); if (\is_array($slash)) { $slashTmp = $slash; $langKey = \array_search('lang', $slash) + 1; unset($slashTmp[$langKey]); if ($langKey == \count($slash) - 1) { unset($slash[$langKey]); $pathBack = \implode('/', $slash); } } $pathBackCache[$path] = $pathBack; } return $pathBackCache[$path]; } /** * Get data for chain links. * * @param string $path Path to analise. * * @return array */ protected function generateChainLinks($path) { static $chainCache = []; if (!isset($chainCache[$path])) { $params =& $this->getParams(); $chain = array(); $slash = \explode('/', \dirname($path)); if (\is_array($slash)) { $langKey = \array_search('lang', $slash) + 1; $slash[$langKey] = $params['CURRENT_LANG']; if ($langKey == \count($slash) - 1) { unset($slash[$langKey]); } $i = 0; $pathList = array(); foreach ($slash as $dir) { $i++; if ($i == 1) { $chain[] = array( 'link' => $params['LIST_PATH']. '?lang='.$params['CURRENT_LANG']. '&tabId='.$this->tabId. '&path=/', 'title' => '..' ); } else { $pathList[] = \htmlspecialcharsbx($dir); $chain[] = array( 'link' => $params['LIST_PATH']. '?lang='.$params['CURRENT_LANG']. '&tabId='.$this->tabId. '&path=/'.\implode('/', $pathList).'/', 'title' => \htmlspecialcharsbx($dir) ); } } } $chainCache[$path] = $chain; } return $chainCache[$path]; } public function getTopIndexedFolders(int $depth = 2): array { static $list; if ($list === null) { $list = [0 => '']; $res = Index\Internals\PathIndexTable::getList([ 'select' => ['ID', 'PATH'], 'filter' => [ '=INDEXED' => 'Y', '=IS_DIR' => 'Y', '<=DEPTH_LEVEL' => $depth, ], 'order' => [ 'DEPTH_LEVEL' => 'ASC', 'PATH' => 'ASC', ] ]); while ($row = $res->fetch()) { $list[$row['ID']] = $row['PATH']; } } return $list; } }