Custom Drush Command to import all .po files

30 / Jul / 2023 by yogendra.singh 0 comments

The main purpose of this blog is to create a custom command to import all .po files. In one step  Portable Object (.po) file is used for localization and content translation.

Let’s start the creation of a custom drush command to import .po files:

Step 1.  Create Module

Create a .info.yml file

name: Custom Drush

type: module

description: This module is used to create custom drush command to import *.po files

package: Custom

core_version_requirement: 8.x || 9.x

Step 2: Create a service using services.yml

Create a drush.services.yml file

services:

 custom_drush.commands:

   class: \Drupal\custom_drush\Commands\AllDrushCommands

   tags:

     - { name: drush.command }

Step 3: Create a Drush Class

Now let’s extend the DrushCommands base class.

Path : custom_drush/src/Commands/AllDrushCommands.php

<?php

namespace Drupal\custom_drush\Commands;

use Drush\Commands\DrushCommands;

/**

* A Drush commandfile.

*

* In addition to this file, you need a drush.services.yml

* in root of your module, and a composer.json file that provides the name

* of the services file to use.

*/

class AllDrushCommands extends DrushCommands {

/**

  *

  * @command custom_drush:ImportPoFiles

  * @aliases import_po_files

  * @usage custom_drush:cmgImportPo

  *   import all .po files.

  */

  public function ImportPoFiles() {

   $today = date("Y-m-d");

   $langcodes = \Drupal::languageManager()->getLanguages();

   $langcodesList = array_keys($langcodes);

   // Get all .po files.

   $arrFiles = glob(DRUPAL_ROOT .'/*.po');

   $this->output()->writeln('Importing po files');

   $starttimer = 'importingpofiles';

   Timer::start($starttimer);

   foreach($arrFiles as $file){

     $file = end(explode('/',$file));

     $file_langcode = substr($file,0,strlen($file)-3);

     if (in_array($file_langcode, $langcodesList)){

       importPoTranslations([$file]);

     }

   }

   drush_backend_batch_process();

   // Time taken.

   $this->output()->writeln('Time taken for importing .po files (seconds) = ' . (Timer::read($starttimer) / 1000));

   $timer_stats = Timer::stop($starttimer)

 }

}

Step 4: Create a method used in drush class

/**

* Function : importPoTranslations

* Param : Array

* Description : To import po files

*/

function importPoTranslations( array $poFiles) {

\Drupal::moduleHandler()->loadInclude('locale', 'translation.inc');

\Drupal::moduleHandler()->loadInclude('locale', 'bulk.inc');

$importer_options = array();

$opt_langcode = '';

$opt_set_customized = TRUE;

$opt_replace_customized = TRUE;

$opt_replace_not_customized = TRUE;

// Import language files.

$files = [];

$langcodes_to_import = [];

foreach ($poFiles as $file_path) {

// Ensure we have the file intended for upload.

if (file_exists($file_path)) {

$opt_langcode = substr($file_path,0,strlen($file_path)-3);

$importer_options = array_merge(_locale_translation_default_update_options(), [

'langcode' => $opt_langcode,

'customized' => $opt_set_customized ? LOCALE_CUSTOMIZED : LOCALE_NOT_CUSTOMIZED,

'overwrite_options' => [

'customized' => (int) $opt_replace_customized,

'not_customized' => (int) $opt_replace_not_customized,

],

]);

$file = locale_translate_file_create($file_path);

$file = locale_translate_file_attach_properties($file, $importer_options);

if ($file->langcode == LanguageInterface::LANGCODE_NOT_SPECIFIED) {

if (!$opt_langcode) {

\Drupal::logger('update')

->error(t('Can not autodetect language of file @file', ['@file' => $file_path]));

return;

}

$file->langcode = $opt_langcode;

if (empty($file->version) && !empty($file->project) && !empty($file->langcode)) {

$sources = locale_translation_get_status();

$source = $sources[$file->project][$file->langcode];

if (isset($source->version)) {

$file->version = $source->version;

}

}

}

$langcodes_to_import[$file->langcode] = $file->langcode;

$files[] = $file;

}

else {

\Drupal::logger('update')

->error(t('File to import at @filepath not found.', ['@filepath' => $file_path]));

}

}

$batch = locale_translate_batch_build($files, $importer_options);

batch_set($batch);

// Create or update all configuration translations for this language.

if ($batch = locale_config_batch_update_components($importer_options, $langcodes_to_import)) {

batch_set($batch);

}

}

Step 5: Clear the cache

Now let’s clear the cache to flush all caches with this command:

drush cr

Now you can use the new command to import *.po files

drush import_po_files

Conclusion

Finally, using this command on a multilingual website, you can import all .po files. No need to import the .po file one by one from the backend. 

Let us know in case of any queries, and please feel free to reach out via comments.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *