You are here

public function DrushLanguageCliService::exportTranslations in Drush Language Commands 8

Export strings of a language as a .po file.

@todo Implement \Drupal\locale\Form\ExportForm::buildForm @todo This can be simplified once https://www.drupal.org/node/2631584 lands in Drupal core.

Parameters

\Symfony\Component\Console\Style\StyleInterface|\Drupal\drush_language\Drush8Io $io: The $io interface of the cli tool calling.

callable $t: The translation function akin to t().

array $options: The command options.

Throws

\Exception Invalid values passed.

File

src/Service/DrushLanguageCliService.php, line 318

Class

DrushLanguageCliService
Class DrushLanguageCliService.

Namespace

Drupal\drush_language\Service

Code

public function exportTranslations($io, callable $t, array $options = [
  'statuses' => [
    'customized',
  ],
  'langcodes' => [],
  'file' => '%langcode.po',
  'force' => TRUE,
]) {

  // Get options.
  $opt_langcodes = $options['langcodes'];
  $opt_filepath = $options['file'];
  $opt_force_write = $options['force'];
  $opt_statuses = $options['statuses'];

  // Massage options.
  // Massage translation statuses.
  $export_statuses_allowed = [
    // internal-value => input-value.
    'customized' => 'customized',
    'not_customized' => 'not-customized',
    'not_translated' => 'not-translated',
  ];
  $opt_statuses = array_values($opt_statuses);
  if ($opt_statuses == [
    'all',
  ]) {
    $opt_statuses = $export_statuses_allowed;
  }
  $export_statuses_unknown = array_diff($opt_statuses, $export_statuses_allowed);
  if ($export_statuses_unknown) {
    $io
      ->error($t('Unknown status options: @options', [
      '@options' => implode(', ', $export_statuses_unknown),
    ]));
    return;
  }
  $export_statuses_filtered = array_intersect($export_statuses_allowed, $opt_statuses);
  $export_statuses = array_fill_keys(array_keys($export_statuses_filtered), TRUE);

  // Massage file path pattern.
  if (!Path::isAbsolute($opt_filepath) && !('./' === substr($opt_filepath, 0, 2))) {
    $opt_filedir = Settings::get('custom_translations_directory');
    if (!$opt_filedir) {
      $io
        ->error($t('Can not export, relative path given and no $settings[\'custom_translations_directory\'] defined. You can instead use an absolute filename or one starting with "./".'));
      return;
    }
    if (!Path::isAbsolute($opt_filedir)) {
      $opt_filedir = DRUPAL_ROOT . DIRECTORY_SEPARATOR . $opt_filedir;
    }
    $opt_filepath = $opt_filedir . DIRECTORY_SEPARATOR . $opt_filepath;
  }

  // Massage langcodes.
  if (!$opt_langcodes) {
    $languages = $this->languageManager
      ->getLanguages();
    $opt_langcodes = array_keys($languages);
  }

  // Validate options.
  // Yell if more than 1 langcode and no placeholder.
  if (count($opt_langcodes) > 1 && !preg_match('/%langcode/u', $opt_filepath)) {
    $io
      ->error($t('You must use %langcode file placeholder when exporting multiple languages.'));
    return;
  }

  // Check that all langcodes are valid, before beginning.
  foreach ($opt_langcodes as $langcode) {
    $language = $this->languageManager
      ->getLanguage($langcode);
    if ($language == NULL) {
      $io
        ->error($t('Unknown language: %langcode', [
        '%langcode' => $langcode,
      ]));
      return;
    }
  }

  // Do our work.
  foreach ($opt_langcodes as $langcode) {
    $filepath = preg_replace('/%langcode/u', $langcode, $opt_filepath);
    $language = $this->languageManager
      ->getLanguage($langcode);

    // Check if file_path exists and is writable.
    $dir = dirname($filepath);
    if (!$this->fileSystem
      ->prepareDirectory($dir)) {
      $this->fileSystem
        ->prepareDirectory($dir, FileSystemInterface::MODIFY_PERMISSIONS | FileSystemInterface::CREATE_DIRECTORY);
    }
    $reader = new PoDatabaseReader();
    $language_name = '';
    if ($language != NULL) {
      $reader
        ->setLangcode($language
        ->getId());
      $reader
        ->setOptions($export_statuses);
      $languages = $this->languageManager
        ->getLanguages();
      $language_name = isset($languages[$language
        ->getId()]) ? $languages[$language
        ->getId()]
        ->getName() : '';
    }
    $item = $reader
      ->readItem();
    if ($item || $opt_force_write) {
      $header = $reader
        ->getHeader();
      $header
        ->setProjectName($this->configFactory
        ->get('system.site')
        ->get('name'));
      $header
        ->setLanguageName($language_name);
      $writer = new PoStreamWriter();
      $writer
        ->setURI($filepath);
      $writer
        ->setHeader($header);
      $writer
        ->open();
      if ($item) {
        $writer
          ->writeItem($item);
      }
      $writer
        ->writeItems($reader);
      $writer
        ->close();
      $io
        ->success($t('Exported translations for language !langcode to file !file.', [
        '!langcode' => $langcode,
        '!file' => $filepath,
      ]));
    }
    else {
      $io
        ->error($t('Nothing to export for language !langcode.', [
        '!langcode' => $langcode,
      ]));
      return;
    }
  }
  $io
    ->success($t('Export complete.'));
}