FileTranslation.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace Drupal\Core\StringTranslation\Translator;
  3. use Drupal\Component\Gettext\PoStreamReader;
  4. use Drupal\Component\Gettext\PoMemoryWriter;
  5. /**
  6. * File based string translation.
  7. *
  8. * Translates a string when some systems are not available.
  9. *
  10. * Used during the install process, when database, theme, and localization
  11. * system is possibly not yet available.
  12. */
  13. class FileTranslation extends StaticTranslation {
  14. /**
  15. * Directory to find translation files in the file system.
  16. *
  17. * @var string
  18. */
  19. protected $directory;
  20. /**
  21. * Constructs a StaticTranslation object.
  22. *
  23. * @param string $directory
  24. * The directory to retrieve file translations from.
  25. */
  26. public function __construct($directory) {
  27. parent::__construct();
  28. $this->directory = $directory;
  29. }
  30. /**
  31. * {@inheritdoc}
  32. */
  33. protected function getLanguage($langcode) {
  34. // If the given langcode was selected, there should be at least one .po
  35. // file with its name in the pattern drupal-$version.$langcode.po.
  36. // This might or might not be the entire filename. It is also possible
  37. // that multiple files end with the same suffix, even if unlikely.
  38. $files = $this->findTranslationFiles($langcode);
  39. if (!empty($files)) {
  40. return $this->filesToArray($langcode, $files);
  41. }
  42. else {
  43. return [];
  44. }
  45. }
  46. /**
  47. * Finds installer translations either for a specific or all languages.
  48. *
  49. * Filenames must match the pattern:
  50. * - 'drupal-[version].[langcode].po (if langcode is provided)
  51. * - 'drupal-[version].*.po (if no langcode is provided)
  52. *
  53. * @param string $langcode
  54. * (optional) The language code corresponding to the language for which we
  55. * want to find translation files. If omitted, information on all available
  56. * files will be returned.
  57. *
  58. * @return array
  59. * An associative array of file information objects keyed by file URIs as
  60. * returned by file_scan_directory().
  61. *
  62. * @see file_scan_directory()
  63. */
  64. public function findTranslationFiles($langcode = NULL) {
  65. $files = file_scan_directory($this->directory, $this->getTranslationFilesPattern($langcode), ['recurse' => FALSE]);
  66. return $files;
  67. }
  68. /**
  69. * Provides translation file name pattern.
  70. *
  71. * @param string $langcode
  72. * (optional) The language code corresponding to the language for which we
  73. * want to find translation files.
  74. *
  75. * @return string
  76. * String file pattern.
  77. */
  78. protected function getTranslationFilesPattern($langcode = NULL) {
  79. // The file name matches: drupal-[release version].[language code].po
  80. // When provided the $langcode is use as language code. If not provided all
  81. // language codes will match.
  82. return '!drupal-[0-9a-z\.-]+\.' . (!empty($langcode) ? preg_quote($langcode, '!') : '[^\.]+') . '\.po$!';
  83. }
  84. /**
  85. * Reads the given Gettext PO files into a data structure.
  86. *
  87. * @param string $langcode
  88. * Language code string.
  89. * @param array $files
  90. * List of file objects with URI properties pointing to read.
  91. *
  92. * @return array
  93. * Structured array as produced by a PoMemoryWriter.
  94. *
  95. * @see \Drupal\Component\Gettext\PoMemoryWriter
  96. */
  97. public static function filesToArray($langcode, array $files) {
  98. $writer = new PoMemoryWriter();
  99. $writer->setLangcode($langcode);
  100. foreach ($files as $file) {
  101. $reader = new PoStreamReader();
  102. $reader->setURI($file->uri);
  103. $reader->setLangcode($langcode);
  104. $reader->open();
  105. $writer->writeItems($reader, -1);
  106. }
  107. return $writer->getData();
  108. }
  109. }