WP_Translation_File_MO::parse_file(): bool

In this article

Parses the file.

Return

bool True on success, false otherwise.

Source

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

	$file_contents = file_get_contents( $this->file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents

	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 ) {
					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;
}

Changelog

VersionDescription
6.5.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.