Title: WP_Translation_File_MO::parse_file
Published: April 3, 2024
Last modified: May 20, 2026

---

# WP_Translation_File_MO::parse_file(): bool

## In this article

 * [Return](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/parse_file/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/parse_file/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/parse_file/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/parse_file/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/parse_file/?output_format=md#wp--skip-link--target)

Parses the file.

## 󠀁[Return](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/parse_file/?output_format=md#return)󠁿

 bool True on success, false otherwise.

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/parse_file/?output_format=md#source)󠁿

    ```php
    protected function parse_file(): bool {
    	$this->parsed = true;

    	$file_contents = file_get_contents( $this->file );

    	if ( false === $file_contents ) {
    		return false;
    	}

    	$file_length = strlen( $file_contents );

    	if ( $file_length < 24 ) {
    		$this->error = 'Invalid data';
    		return false;
    	}

    	$this->uint32 = $this->detect_endian_and_validate_file( substr( $file_contents, 0, 4 ) );

    	if ( false === $this->uint32 ) {
    		return false;
    	}

    	$offsets = substr( $file_contents, 4, 24 );

    	if ( false === $offsets ) {
    		return false;
    	}

    	$offsets = unpack( "{$this->uint32}rev/{$this->uint32}total/{$this->uint32}originals_addr/{$this->uint32}translations_addr/{$this->uint32}hash_length/{$this->uint32}hash_addr", $offsets );

    	if ( false === $offsets ) {
    		return false;
    	}

    	$offsets['originals_length']    = $offsets['translations_addr'] - $offsets['originals_addr'];
    	$offsets['translations_length'] = $offsets['hash_addr'] - $offsets['translations_addr'];

    	if ( $offsets['rev'] > 0 ) {
    		$this->error = 'Unsupported revision';
    		return false;
    	}

    	if ( $offsets['translations_addr'] > $file_length || $offsets['originals_addr'] > $file_length ) {
    		$this->error = 'Invalid data';
    		return false;
    	}

    	// Load the Originals.
    	$original_data     = str_split( substr( $file_contents, $offsets['originals_addr'], $offsets['originals_length'] ), 8 );
    	$translations_data = str_split( substr( $file_contents, $offsets['translations_addr'], $offsets['translations_length'] ), 8 );

    	foreach ( array_keys( $original_data ) as $i ) {
    		$o = unpack( "{$this->uint32}length/{$this->uint32}pos", $original_data[ $i ] );
    		$t = unpack( "{$this->uint32}length/{$this->uint32}pos", $translations_data[ $i ] );

    		if ( false === $o || false === $t ) {
    			continue;
    		}

    		$original    = substr( $file_contents, $o['pos'], $o['length'] );
    		$translation = substr( $file_contents, $t['pos'], $t['length'] );
    		// GlotPress bug.
    		$translation = rtrim( $translation, "\0" );

    		// Metadata about the MO file is stored in the first translation entry.
    		if ( '' === $original ) {
    			foreach ( explode( "\n", $translation ) as $meta_line ) {
    				if ( '' === $meta_line || ! str_contains( $meta_line, ':' ) ) {
    					continue;
    				}

    				list( $name, $value ) = array_map( 'trim', explode( ':', $meta_line, 2 ) );

    				$this->headers[ strtolower( $name ) ] = $value;
    			}
    		} else {
    			/*
    			 * In MO files, the key normally contains both singular and plural versions.
    			 * However, this just adds the singular string for lookup,
    			 * which caters for cases where both __( 'Product' ) and _n( 'Product', 'Products' )
    			 * are used and the translation is expected to be the same for both.
    			 */
    			$parts = explode( "\0", (string) $original );

    			$this->entries[ $parts[0] ] = $translation;
    		}
    	}

    	return true;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/l10n/class-wp-translation-file-mo.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.0/src/wp-includes/l10n/class-wp-translation-file-mo.php#L90)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.0/src/wp-includes/l10n/class-wp-translation-file-mo.php#L90-L179)

## 󠀁[Related](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/parse_file/?output_format=md#related)󠁿

| Uses | Description | 
| [WP_Translation_File_MO::detect_endian_and_validate_file()](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/detect_endian_and_validate_file/)`wp-includes/l10n/class-wp-translation-file-mo.php` |

Detects endian and validates file.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wp_translation_file_mo/parse_file/?output_format=md#changelog)󠁿

| Version | Description | 
| [6.5.0](https://developer.wordpress.org/reference/since/6.5.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwp_translation_file_mo%2Fparse_file%2F)
before being able to contribute a note or feedback.