• Модуль: translate
  • Путь к файлу: ~/bitrix/modules/translate/lib/file.php
  • Класс: BitrixTranslateFile
  • Вызов: File::loadTokens
public function loadTokens(): bool
{
	$this->messages = [];
	$this->messageCodes = [];
	$this->messageEnclosure = [];
	$this->messagesCount = 0;

	if (!$this->isExists() || !$this->isFile() || ($this->getExtension() !== 'php'))
	{
		return false;
	}

	// language id
	$langId = $this->getLangId();
	if (empty($langId))
	{
		$this->addError(new MainError('Language Id must be filled'));
		return false;
	}

	$content = $this->getContents();
	if (
		empty($content)
		|| !is_string($content)
		|| $content === 'addError(new MainError('Empty content', 'EMPTY_CONTENT'));
		return false;
	}

	$is = function ($token, $type, $value = null)
	{
		if (is_string($token))
		{
			return $token === $type;
		}
		if (is_array($token))
		{
			if ($token[0] === $type)
			{
				if ($value !== null)
				{
					return $token[1] === $value;
				}
				return true;
			}
		}
		return false;
	};

	$tokens = token_get_all($content);

	$hasPhraseDefinition = false;
	foreach ($tokens as $inx => $token)
	{
		if ($is($token, T_WHITESPACE))
		{
			unset($tokens[$inx]);
			continue;
		}
		if (!$hasPhraseDefinition && $is($token, T_VARIABLE, '$MESS'))
		{
			$hasPhraseDefinition = true;
		}
		//if (is_array($token))$tokens[$inx][] = token_name($token[0]);
	}

	if (!$hasPhraseDefinition)
	{
		$this->addError(new MainError("There are no phrase definitions"));
		return false;
	}

	array_splice($tokens, 0, 0);

	$addPhrase = function ($phraseId, $phraseParts, $isHeredoc = false)
	{
		if ($phraseId != '')
		{
			$len = mb_strlen($phraseId, $this->getOperatingEncoding());
			$phraseId = mb_substr($phraseId, 1, $len - 2, $this->getOperatingEncoding());// strip trailing quotes
			$phraseId = str_replace("\\", "\", $phraseId);// strip slashes in code

			$enclosure = $isHeredoc ? '<<<' : mb_substr($phraseParts[0], 0, 1);// what quote

			$phrase = '';
			if ($isHeredoc)
			{
				$part = $phraseParts[0];
				$len = mb_strlen($part, $this->getOperatingEncoding());
				$phrase = mb_substr($part, 0, $len - 1, $this->getOperatingEncoding());// strip final n
			}
			else
			{
				foreach ($phraseParts as $part)
				{
					$enclosure = mb_substr($part, 0, 1);// what quote
					// strip trailing quotes
					if ($enclosure === '"' || $enclosure === "'")
					{
						$len = mb_strlen($part, $this->getOperatingEncoding());
						$part = mb_substr($part, 1, $len - 2, $this->getOperatingEncoding());
					}
					//$part = StringHelper::unescapePhp($part, $enclosure);
					$phrase .= $part;
				}
			}

			$this->messages[$phraseId] = $phrase;
			$this->messageCodes[] = $phraseId;
			$this->messageEnclosure[$phraseId] = $enclosure;
			$this->messagesCount++;
		}
	};

	$startPhrase = false;
	$endPhrase = false;
	$inPhrase = false;
	$inCode = false;
	$isHeredoc = false;
	$phraseId = '';
	$phrase = [];
	$whereIsPhrase = [];

	foreach ($tokens as $inx => &$token)
	{
		if (!$startPhrase && $is($token, T_VARIABLE, '$MESS'))
		{
			$startPhrase = true;
		}

		if ($startPhrase)
		{
			if ($is($token, '['))
			{
				$inCode = true;
			}
			elseif ($is($token, ']'))
			{
				$inCode = false;
			}
			elseif ($is($token, '='))
			{
				$inPhrase = true;
			}
			elseif ($is($token, ';'))
			{
				$endPhrase = true;
			}
			elseif ($is($token, T_CLOSE_TAG))
			{
				$endPhrase = true;
			}
			elseif ($is($token, T_START_HEREDOC))
			{
				$isHeredoc = true;
			}

			if (
				$inPhrase
				&& $is($token, T_VARIABLE, '$MESS')
				&& $is($tokens[$inx + 1], '[')
				&& $is($tokens[$inx + 2], T_CONSTANT_ENCAPSED_STRING)
			)
			{
				$clonePhraseId = $tokens[$inx + 2][1];
				$cloneInx = $whereIsPhrase[$clonePhraseId];
				$phrase[] = $tokens[$cloneInx][1];
				$endPhrase = true;
			}

			if ($is($token, T_CONSTANT_ENCAPSED_STRING) || $is($token, T_ENCAPSED_AND_WHITESPACE))
			{
				if ($inPhrase)
				{
					$phrase[] = $token[1];
					$whereIsPhrase[$phraseId] = $inx;
				}
				if ($inCode)
				{
					$phraseId = $token[1];
				}
			}

			if ($endPhrase)
			{
				$addPhrase($phraseId, $phrase, $isHeredoc);

				$phrase = [];
				$phraseId = '';
				$startPhrase = false;
				$endPhrase = false;
				$inPhrase = false;
				$inCode = false;
				$isHeredoc = false;
			}
		}

		// todo: Handle here developer's comment from file
		// T_COMMENT T_DOC_COMMENT
	}

	if ($startPhrase)
	{
		$addPhrase($phraseId, $phrase, $isHeredoc);
	}

	return true;
}