wp/wp-includes/l10n/class-wp-translation-file-mo.php
author ymh <ymh.work@gmail.com>
Fri, 05 Sep 2025 18:52:52 +0200
changeset 22 8c2e4d02f4ef
parent 21 48c4eec2b7e6
permissions -rw-r--r--
Update WordPress to latest version (6.7) - Sync WordPress core files from latest release - Updated admin interface, blocks, and core functionality - Enhanced block editor features and performance - Security updates and bug fixes - Preserved custom wp-content directory and configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
21
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
/**
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
 * I18N: WP_Translation_File_MO class.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
 * @package WordPress
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
 * @subpackage I18N
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
 * @since 6.5.0
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
 */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
/**
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 * Class WP_Translation_File_MO.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
 * @since 6.5.0
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
class WP_Translation_File_MO extends WP_Translation_File {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
	/**
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
	 * Endian value.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
	 * V for little endian, N for big endian, or false.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
	 * Used for unpack().
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
	 * @since 6.5.0
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
	 * @var false|'V'|'N'
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
	 */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
	protected $uint32 = false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
	/**
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
	 * The magic number of the GNU message catalog format.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
	 * @since 6.5.0
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
	 * @var int
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
	 */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
	const MAGIC_MARKER = 0x950412de;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
	/**
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
	 * Detects endian and validates file.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
	 * @since 6.5.0
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
	 * @param string $header File contents.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
	 * @return false|'V'|'N' V for little endian, N for big endian, or false on failure.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
	 */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
	protected function detect_endian_and_validate_file( string $header ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
		$big = unpack( 'N', $header );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
		if ( false === $big ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
		$big = reset( $big );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
		if ( false === $big ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
		$little = unpack( 'V', $header );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
		if ( false === $little ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
		$little = reset( $little );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
		if ( false === $little ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
		// Force cast to an integer as it can be a float on x86 systems. See https://core.trac.wordpress.org/ticket/60678.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
		if ( (int) self::MAGIC_MARKER === $big ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
			return 'N';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
		// Force cast to an integer as it can be a float on x86 systems. See https://core.trac.wordpress.org/ticket/60678.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
		if ( (int) self::MAGIC_MARKER === $little ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
			return 'V';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
		$this->error = 'Magic marker does not exist';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
		return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
	}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
	/**
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
	 * Parses the file.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
	 * @since 6.5.0
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
	 * @return bool True on success, false otherwise.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
	 */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
	protected function parse_file(): bool {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
		$this->parsed = true;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
		$file_contents = file_get_contents( $this->file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
		if ( false === $file_contents ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
		$file_length = strlen( $file_contents );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
		if ( $file_length < 24 ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
			$this->error = 'Invalid data';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
		$this->uint32 = $this->detect_endian_and_validate_file( substr( $file_contents, 0, 4 ) );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
		if ( false === $this->uint32 ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
		$offsets = substr( $file_contents, 4, 24 );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
		if ( false === $offsets ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
		$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 );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
		if ( false === $offsets ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
		$offsets['originals_length']    = $offsets['translations_addr'] - $offsets['originals_addr'];
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
		$offsets['translations_length'] = $offsets['hash_addr'] - $offsets['translations_addr'];
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
		if ( $offsets['rev'] > 0 ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
			$this->error = 'Unsupported revision';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
		if ( $offsets['translations_addr'] > $file_length || $offsets['originals_addr'] > $file_length ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
			$this->error = 'Invalid data';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
			return false;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
		// Load the Originals.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
		$original_data     = str_split( substr( $file_contents, $offsets['originals_addr'], $offsets['originals_length'] ), 8 );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
		$translations_data = str_split( substr( $file_contents, $offsets['translations_addr'], $offsets['translations_length'] ), 8 );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
		foreach ( array_keys( $original_data ) as $i ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
			$o = unpack( "{$this->uint32}length/{$this->uint32}pos", $original_data[ $i ] );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
			$t = unpack( "{$this->uint32}length/{$this->uint32}pos", $translations_data[ $i ] );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
			if ( false === $o || false === $t ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
				continue;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
			}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
			$original    = substr( $file_contents, $o['pos'], $o['length'] );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
			$translation = substr( $file_contents, $t['pos'], $t['length'] );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
			// GlotPress bug.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
			$translation = rtrim( $translation, "\0" );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
			// Metadata about the MO file is stored in the first translation entry.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
			if ( '' === $original ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
				foreach ( explode( "\n", $translation ) as $meta_line ) {
22
8c2e4d02f4ef Update WordPress to latest version (6.7)
ymh <ymh.work@gmail.com>
parents: 21
diff changeset
   157
					if ( '' === $meta_line || ! str_contains( $meta_line, ':' ) ) {
21
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
						continue;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
					}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
					list( $name, $value ) = array_map( 'trim', explode( ':', $meta_line, 2 ) );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
					$this->headers[ strtolower( $name ) ] = $value;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
				}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
			} else {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
				/*
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
				 * In MO files, the key normally contains both singular and plural versions.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
				 * However, this just adds the singular string for lookup,
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
				 * which caters for cases where both __( 'Product' ) and _n( 'Product', 'Products' )
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
				 * are used and the translation is expected to be the same for both.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
				 */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
				$parts = explode( "\0", (string) $original );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
				$this->entries[ $parts[0] ] = $translation;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
			}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
		return true;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
	}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
	/**
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
	 * Exports translation contents as a string.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
	 * @since 6.5.0
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
	 *
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
	 * @return string Translation file contents.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
	 */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
	public function export(): string {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
		// Prefix the headers as the first key.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
		$headers_string = '';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
		foreach ( $this->headers as $header => $value ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
			$headers_string .= "{$header}: $value\n";
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   193
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
		$entries     = array_merge( array( '' => $headers_string ), $this->entries );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
		$entry_count = count( $entries );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
		if ( false === $this->uint32 ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   198
			$this->uint32 = 'V';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   199
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   200
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
		$bytes_for_entries = $entry_count * 4 * 2;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
		// Pair of 32bit ints per entry.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
		$originals_addr    = 28; /* header */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   204
		$translations_addr = $originals_addr + $bytes_for_entries;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   205
		$hash_addr         = $translations_addr + $bytes_for_entries;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   206
		$entry_offsets     = $hash_addr;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   208
		$file_header = pack(
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   209
			$this->uint32 . '*',
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   210
			// Force cast to an integer as it can be a float on x86 systems. See https://core.trac.wordpress.org/ticket/60678.
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   211
			(int) self::MAGIC_MARKER,
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   212
			0, /* rev */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   213
			$entry_count,
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   214
			$originals_addr,
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   215
			$translations_addr,
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   216
			0, /* hash_length */
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   217
			$hash_addr
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   218
		);
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   219
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   220
		$o_entries = '';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   221
		$t_entries = '';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   222
		$o_addr    = '';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   223
		$t_addr    = '';
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   224
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   225
		foreach ( array_keys( $entries ) as $original ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   226
			$o_addr        .= pack( $this->uint32 . '*', strlen( $original ), $entry_offsets );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   227
			$entry_offsets += strlen( $original ) + 1;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   228
			$o_entries     .= $original . "\0";
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   229
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   230
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   231
		foreach ( $entries as $translations ) {
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   232
			$t_addr        .= pack( $this->uint32 . '*', strlen( $translations ), $entry_offsets );
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   233
			$entry_offsets += strlen( $translations ) + 1;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   234
			$t_entries     .= $translations . "\0";
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   235
		}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   236
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   237
		return $file_header . $o_addr . $t_addr . $o_entries . $t_entries;
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   238
	}
48c4eec2b7e6 Add CLAUDE.md documentation and sync WordPress core files
ymh <ymh.work@gmail.com>
parents:
diff changeset
   239
}