symfony_translation-1.0.0-alpha1/src/Translator/TranslatorFactory.php
src/Translator/TranslatorFactory.php
<?php
namespace Drupal\symfony_translation\Translator;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\symfony_translation\SymfonyTranslation;
use Symfony\Component\Translation\Loader\LoaderInterface;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* A factory for creating translator instances.
*/
class TranslatorFactory {
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The filesystem service.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/**
* The cache backend.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* The translation loaders.
*
* @var \Symfony\Component\Translation\Loader\LoaderInterface[]
*/
protected $loaders = [];
/**
* Constructs a TranslatorFactory object.
*
* @param \Drupal\Core\Language\LanguageManagerInterface $languageManager
* The language manager service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
* @param \Drupal\Core\File\FileSystemInterface $fileSystem
* The filesystem service.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend.
*/
public function __construct(
LanguageManagerInterface $languageManager,
ConfigFactoryInterface $configFactory,
FileSystemInterface $fileSystem,
CacheBackendInterface $cache
) {
$this->languageManager = $languageManager;
$this->configFactory = $configFactory;
$this->fileSystem = $fileSystem;
$this->cache = $cache;
}
/**
* Adds a translation loader.
*
* @param \Symfony\Component\Translation\Loader\LoaderInterface $loader
* The translation loader.
* @param string $alias
* The alias of the loader.
* @param string|null $legacyAlias
* The legacy alias of the loader.
*/
public function addLoader(LoaderInterface $loader, string $alias, ?string $legacyAlias = NULL): void {
$this->loaders[$alias] = $loader;
if (isset($legacyAlias)) {
$this->loaders[$legacyAlias] = $loader;
}
}
/**
* Creates a translator instance.
*/
public function getTranslator(): TranslatorInterface {
$langcode = $this->languageManager->getDefaultLanguage()->getId();
$cacheDir = SymfonyTranslation::getCacheDirectory();
$translator = new Translator($langcode, NULL, $cacheDir);
$translator->setLanguageManager($this->languageManager);
foreach ($this->loaders as $format => $loader) {
$translator->addLoader($format, $loader);
}
foreach ($this->getTranslationFiles() as $file) {
$translator->addResource($file['format'], $file['path'], $file['langcode'], $file['domain']);
}
return $translator;
}
/**
* Get the paths of translation files that should be parsed.
*/
protected function getTranslationFiles(): array {
if ($cached = $this->cache->get('symfony_translation.translation_files')) {
return array_filter($cached->data, function (array $file) {
return file_exists($file['path']);
});
}
$settings = $this->configFactory->get('symfony_translation.settings');
$projectTranslationDir = DRUPAL_ROOT . DIRECTORY_SEPARATOR . ltrim($settings->get('folder') ?: '../translations', DIRECTORY_SEPARATOR);
$result = $this->fileSystem->prepareDirectory($projectTranslationDir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
if ($result === FALSE) {
throw new \RuntimeException(sprintf('Could not create translation directory "%s".', $projectTranslationDir));
}
$projectTranslationDir = $this->fileSystem->realpath($projectTranslationDir);
$regex = sprintf('#%s\/((?<domain>.+)(\.|\\|\/))?(?<langcode>.+)\.(?<extension>.+)$#', preg_quote($projectTranslationDir));
$dirIterator = new \RecursiveDirectoryIterator($projectTranslationDir);
$iteratorIterator = new \RecursiveIteratorIterator($dirIterator);
$regexIterator = new \RegexIterator($iteratorIterator, $regex, \RegexIterator::GET_MATCH);
$files = [];
foreach ($regexIterator as $result) {
if (is_dir($result[0])) {
continue;
}
$isIntlFile = substr($result['domain'], -strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX)) === MessageCatalogue::INTL_DOMAIN_SUFFIX;
$file['path'] = $result[0];
$file['domain'] = $result['domain'] ?? 'messages';
$file['langcode'] = $result['langcode'];
$file['format'] = $result['extension'];
if (!isset($file['langcode']) || !isset($file['format'])) {
continue;
}
if ($isIntlFile && $settings->get('mode') !== 'standalone') {
continue;
}
$files[] = $file;
}
$this->cache->set('symfony_translation.translation_files', $files);
return $files;
}
}
