Search code examples
phpwordpressinternationalizationpo

PO files translations: going backwords, from msgstr to msgid?


I'm in need to start from the msgstr to retrieve the msgid. The reason is that I've got several translations, all EN to SOME OTHER LANG, but now in the current installation I need to go back from SOME OTHER LANG to EN. Note that I'm also working in WordPress, maybe this is not important though. There are a couple of similar questions here but not exactly what I need.

So is there a way to accomplish this?


Solution

  • WordPress ships with a PO reader and writer as part of the pomo package. Below is a pretty simple script that swaps the msgid and msgstr fields around and writes out a new file.

    As already pointed out in the comments, there are several things that make this potentially problematic:

    1. Your target strings must all be unique (and not empty)
    2. If you have message context, this will stay in the original language.
    3. Your original language must have only two plural forms.

    Onward -

    <?php
    require_once 'path/to/wp-includes/pomo/po.php';
    $source_file = 'path/to/languages/old-file.po';
    $target_file = 'path/to/languages/new-file.po';
    
    // parse original message catalogue from source file
    $source = new PO;
    $source->import_from_file($source_file);
    
    // prep target messages with a different language
    $target = new PO;
    $target->set_headers( $source->headers );
    $target->set_header('Language', 'en_US');
    $target->set_header('Language-Team', 'English from SOME OTHER LANG');
    $target->set_header('Plural-Forms', 'nplurals=2; plural=n!=1;');
    
    /* @var Translation_Entry $entry */
    foreach( $source->entries as $entry ){
        $reversed = clone $entry;
        // swap msgid and msgstr (singular)
        $reversed->singular = $entry->translations[0];
        $reversed->translations[0] = $entry->singular;
        // swap msgid_plural and msgstr[2] (plural)
        if( $entry->is_plural ){
            $reversed->plural = $entry->translations[1];
            $reversed->translations[1] = $entry->plural;
        }
        // append target file with modified entry
        $target->add_entry( $reversed );
    }
    
    // write final file back to disk
    file_put_contents( $target_file, $target->export() );