Current Path : /var/www/www-root/data/www.catalog.monolith-realty.ru/bitrix/modules/translate/lib/ |
Current File : /var/www/www-root/data/www.catalog.monolith-realty.ru/bitrix/modules/translate/lib/settings.php |
<?php namespace Bitrix\Translate; use Bitrix\Main; use Bitrix\Translate; class Settings extends Translate\IO\File implements \Iterator, \Countable, \ArrayAccess { public const FILE_NAME = '.settings.php'; public const OPTION_LANGUAGES = 'languages'; /** @var string[] */ protected $options; /** @var int */ protected $optionsCount; /** @var array */ protected $optionCodes = []; /** @var int */ protected $dataPosition = 0; /** * Constructs instance by lang path. * * @param string $fullPath Full path to language file. * * @return Translate\Settings|null * @throws Main\ArgumentException */ public static function instantiateByPath(string $fullPath): ?self { if (empty($fullPath)) { throw new Main\ArgumentException(); } $file = null; if (\mb_substr($fullPath, -5) === '/lang' || \mb_substr($fullPath, -6) === '/lang/') { $file = new static($fullPath. '/'. self::FILE_NAME); } elseif (preg_match("#^(.*?/lang/)([^/]+)/*(.+)#".(Translate\Config::isUtfMode() ? 'u' : ''), $fullPath, $parts)) { $file = new static($parts[1]. '/'. self::FILE_NAME); } return $file; } //region Load & Save /** * Returns option for file/folder. * * @param string $langPath Path to language file. * @param string $optionType Option type. * * @return array */ public function getOption(string $langPath, string $optionType): array { $options = $this->getOptions($langPath); if (!empty($options[$optionType])) { return $options[$optionType]; } return []; } /** * Returns option for file/folder. * * @param string $langPath Path to language file. * * @return array */ public function getOptions(string $langPath = ''): array { // lazy load if ($this->options === null && !$this->load()) { return []; } if (empty($langPath)) { return $this->options; } // for all in lang/ if ($langPath === '*' && isset($this->options['*'])) { return $this->options['*']; } $options = []; if (isset($this->options['*'])) { $options = $this->options['*']; } if (\preg_match("#^(.*?/lang/)([^/]+)/+(.+)#".(Translate\Config::isUtfMode() ? 'u' : ''), $langPath, $parts)) { $langPath = $parts[3]; } if (isset($this->options[$langPath])) { $options = $this->options[$langPath]; } else { if (\mb_strpos($langPath, '/') !== false) { $parts = \explode('/', $langPath); $path = ''; foreach ($parts as $part) { $path .= ($path != '' ? '/' : ''). $part; if (isset($this->options[$path])) { $options = $this->options[$path]; } } } } return $options; } //endregion //region Load & Save /** * Loads option file for operate. * * @return bool */ public function load(): bool { if (!$this->isExists() || !$this->isFile() || $this->getName() !== self::FILE_NAME) { return false; } $this->options = []; $this->optionCodes = []; $this->optionsCount = 0; $options = include $this->getPhysicalPath(); if (\is_array($options) && \count($options) > 0) { $this->options = $options; $this->optionCodes = \array_keys($options); $this->optionsCount = \count($options); } return true; } /** * Save changes or create new file. * * @return boolean * @throws Main\IO\IoException */ public function save(): bool { $content = ''; if ($this->count() > 0) { $content = \var_export($this->options, true); $content = \preg_replace("/^[ ]{6}(.*)/m", "\t\t\t$1", $content); $content = \preg_replace("/^[ ]{4}(.*)/m", "\t\t$1", $content); $content = \preg_replace("/^[ ]{2}(.*)/m", "\t$1", $content); $content = \str_replace(["\r\n", "\r"], ["\n", ''], $content); } \set_error_handler( function ($severity, $message, $file, $line) { throw new \ErrorException($message, $severity, $severity, $file, $line); } ); try { if ($content <> '') { if (parent::putContents("<". "?php\nreturn ". $content. "\n?". '>') === false) { $filePath = $this->getPath(); throw new Main\IO\IoException("Couldn't write option file '{$filePath}'"); } } elseif ($this->isExists()) { $this->markWritable(); $this->delete(); } } catch (\ErrorException $exception) { \restore_error_handler(); throw new Main\IO\IoException($exception->getMessage()); } \restore_error_handler(); return true; } //endregion //region ArrayAccess /** * @param string $code Phrase code. * * @return boolean */ public function offsetExists($code): bool { return isset($this->options[$code]); } /** * @param string $code Phrase code. * * @return string|null */ #[\ReturnTypeWillChange] public function offsetGet($code) { if (isset($this->options[$code])) { return $this->options[$code]; } return null; } /** * Offset to set * * @param string $code Phrase code. * @param string $phrase Phrase. * * @return void */ public function offsetSet($code, $phrase): void { $this->options[$code] = $phrase; } /** * Unset phrase by code. * * @param string $code Language code. * * @return void */ public function offsetUnset($code): void { unset($this->options[$code]); } //endregion //region Iterator /** * Return the current phrase element. * * @return array|null */ #[\ReturnTypeWillChange] public function current() { $code = $this->optionCodes[$this->dataPosition]; return $this->options[$code] ?: null; } /** * Move forward to next phrase element. * * @return void */ public function next(): void { ++ $this->dataPosition; } /** * Return the key of the current phrase element. * * @return string|null */ public function key(): ?string { return $this->optionCodes[$this->dataPosition] ?: null; } /** * Checks if current position is valid. * * @return boolean */ public function valid(): bool { $code = $this->optionCodes[$this->dataPosition]; return isset($this->options[$code]); } /** * Rewind the Iterator to the first element. * * @return void */ public function rewind(): void { $this->dataPosition = 0; $this->optionCodes = \array_keys($this->options); } //endregion //region Countable /** * Returns amount phrases in the language file. * * @param bool $allowDirectFileAccess Allow include file to count phrases. * * @return int */ public function count($allowDirectFileAccess = false): int { if ($this->optionsCount === null) { if ($this->options !== null && \count($this->options) > 0) { $this->optionsCount = \count($this->options); } elseif ($allowDirectFileAccess) { $options = include $this->getPhysicalPath(); if (\is_array($options) && \count($options) > 0) { $this->optionsCount = \count($options); } } } return $this->optionsCount ?: 0; } //endregion }