web/wp-includes/pomo/mo.php
changeset 204 09a1c134465b
parent 194 32102edaa81b
equal deleted inserted replaced
203:f507feede89a 204:09a1c134465b
     1 <?php
     1 <?php
     2 /**
     2 /**
     3  * Class for working with MO files
     3  * Class for working with MO files
     4  *
     4  *
     5  * @version $Id: mo.php 602 2011-01-30 12:43:29Z nbachiyski $
     5  * @version $Id: mo.php 718 2012-10-31 00:32:02Z nbachiyski $
     6  * @package pomo
     6  * @package pomo
     7  * @subpackage mo
     7  * @subpackage mo
     8  */
     8  */
     9 
     9 
    10 require_once dirname(__FILE__) . '/translations.php';
    10 require_once dirname(__FILE__) . '/translations.php';
    32 		if ( !$fh ) return false;
    32 		if ( !$fh ) return false;
    33 		$res = $this->export_to_file_handle( $fh );
    33 		$res = $this->export_to_file_handle( $fh );
    34 		fclose($fh);
    34 		fclose($fh);
    35 		return $res;
    35 		return $res;
    36 	}
    36 	}
    37 	
    37 
    38 	function export() {
    38 	function export() {
    39 		$tmp_fh = fopen("php://temp", 'r+');
    39 		$tmp_fh = fopen("php://temp", 'r+');
    40 		if ( !$tmp_fh ) return false;
    40 		if ( !$tmp_fh ) return false;
    41 		$this->export_to_file_handle( $tmp_fh );
    41 		$this->export_to_file_handle( $tmp_fh );
    42 		rewind( $tmp_fh );
    42 		rewind( $tmp_fh );
    43 		return stream_get_contents( $tmp_fh );
    43 		return stream_get_contents( $tmp_fh );
    44 	}
    44 	}
    45 	
    45 
       
    46 	function is_entry_good_for_export( $entry ) {
       
    47 		if ( empty( $entry->translations ) ) {
       
    48 			return false;
       
    49 		}
       
    50 
       
    51 		if ( !array_filter( $entry->translations ) ) {
       
    52 			return false;
       
    53 		}
       
    54 
       
    55 		return true;
       
    56 	}
       
    57 
    46 	function export_to_file_handle($fh) {
    58 	function export_to_file_handle($fh) {
    47 		$entries = array_filter($this->entries, create_function('$e', 'return !empty($e->translations);'));
    59 		$entries = array_filter( $this->entries, array( $this, 'is_entry_good_for_export' ) );
    48 		ksort($entries);
    60 		ksort($entries);
    49 		$magic = 0x950412de;
    61 		$magic = 0x950412de;
    50 		$revision = 0;
    62 		$revision = 0;
    51 		$total = count($entries) + 1; // all the headers are one entry
    63 		$total = count($entries) + 1; // all the headers are one entry
    52 		$originals_lenghts_addr = 28;
    64 		$originals_lenghts_addr = 28;
    55 		$hash_addr = $translations_lenghts_addr + 8 * $total;
    67 		$hash_addr = $translations_lenghts_addr + 8 * $total;
    56 		$current_addr = $hash_addr;
    68 		$current_addr = $hash_addr;
    57 		fwrite($fh, pack('V*', $magic, $revision, $total, $originals_lenghts_addr,
    69 		fwrite($fh, pack('V*', $magic, $revision, $total, $originals_lenghts_addr,
    58 			$translations_lenghts_addr, $size_of_hash, $hash_addr));
    70 			$translations_lenghts_addr, $size_of_hash, $hash_addr));
    59 		fseek($fh, $originals_lenghts_addr);
    71 		fseek($fh, $originals_lenghts_addr);
    60 		
    72 
    61 		// headers' msgid is an empty string
    73 		// headers' msgid is an empty string
    62 		fwrite($fh, pack('VV', 0, $current_addr));
    74 		fwrite($fh, pack('VV', 0, $current_addr));
    63 		$current_addr++;
    75 		$current_addr++;
    64 		$originals_table = chr(0);
    76 		$originals_table = chr(0);
    65 
    77 
    67 			$originals_table .= $this->export_original($entry) . chr(0);
    79 			$originals_table .= $this->export_original($entry) . chr(0);
    68 			$length = strlen($this->export_original($entry));
    80 			$length = strlen($this->export_original($entry));
    69 			fwrite($fh, pack('VV', $length, $current_addr));
    81 			fwrite($fh, pack('VV', $length, $current_addr));
    70 			$current_addr += $length + 1; // account for the NULL byte after
    82 			$current_addr += $length + 1; // account for the NULL byte after
    71 		}
    83 		}
    72 		
    84 
    73 		$exported_headers = $this->export_headers();
    85 		$exported_headers = $this->export_headers();
    74 		fwrite($fh, pack('VV', strlen($exported_headers), $current_addr));
    86 		fwrite($fh, pack('VV', strlen($exported_headers), $current_addr));
    75 		$current_addr += strlen($exported_headers) + 1;
    87 		$current_addr += strlen($exported_headers) + 1;
    76 		$translations_table = $exported_headers . chr(0);
    88 		$translations_table = $exported_headers . chr(0);
    77 		
    89 
    78 		foreach($entries as $entry) {
    90 		foreach($entries as $entry) {
    79 			$translations_table .= $this->export_translations($entry) . chr(0);
    91 			$translations_table .= $this->export_translations($entry) . chr(0);
    80 			$length = strlen($this->export_translations($entry));
    92 			$length = strlen($this->export_translations($entry));
    81 			fwrite($fh, pack('VV', $length, $current_addr));
    93 			fwrite($fh, pack('VV', $length, $current_addr));
    82 			$current_addr += $length + 1;
    94 			$current_addr += $length + 1;
    83 		}
    95 		}
    84 		
    96 
    85 		fwrite($fh, $originals_table);
    97 		fwrite($fh, $originals_table);
    86 		fwrite($fh, $translations_table);
    98 		fwrite($fh, $translations_table);
    87 		return true;
    99 		return true;
    88 	}
   100 	}
    89 	
   101 
    90 	function export_original($entry) {
   102 	function export_original($entry) {
    91 		//TODO: warnings for control characters
   103 		//TODO: warnings for control characters
    92 		$exported = $entry->singular;
   104 		$exported = $entry->singular;
    93 		if ($entry->is_plural) $exported .= chr(0).$entry->plural;
   105 		if ($entry->is_plural) $exported .= chr(0).$entry->plural;
    94 		if (!is_null($entry->context)) $exported = $entry->context . chr(4) . $exported;
   106 		if (!is_null($entry->context)) $exported = $entry->context . chr(4) . $exported;
    95 		return $exported;
   107 		return $exported;
    96 	}
   108 	}
    97 	
   109 
    98 	function export_translations($entry) {
   110 	function export_translations($entry) {
    99 		//TODO: warnings for control characters
   111 		//TODO: warnings for control characters
   100 		return implode(chr(0), $entry->translations);
   112 		return implode(chr(0), $entry->translations);
   101 	}
   113 	}
   102 	
   114 
   103 	function export_headers() {
   115 	function export_headers() {
   104 		$exported = '';
   116 		$exported = '';
   105 		foreach($this->headers as $header => $value) {
   117 		foreach($this->headers as $header => $value) {
   106 			$exported.= "$header: $value\n";
   118 			$exported.= "$header: $value\n";
   107 		}
   119 		}
   193 
   205 
   194 			$original    = $reader->substr( $strings, $o['pos'], $o['length'] );
   206 			$original    = $reader->substr( $strings, $o['pos'], $o['length'] );
   195 			$translation = $reader->substr( $strings, $t['pos'], $t['length'] );
   207 			$translation = $reader->substr( $strings, $t['pos'], $t['length'] );
   196 
   208 
   197 			if ('' === $original) {
   209 			if ('' === $original) {
   198 				$headers = $this->make_headers($translation);
   210 				$this->set_headers($this->make_headers($translation));
   199 				$this->set_headers($headers);
       
   200 			} else {
   211 			} else {
   201 				$entry = &$this->make_entry($original, $translation);
   212 				$entry = &$this->make_entry($original, $translation);
   202 				$this->entries[$entry->key()] = &$entry;
   213 				$this->entries[$entry->key()] = &$entry;
   203 			}
   214 			}
   204 		}
   215 		}
   206 	}
   217 	}
   207 
   218 
   208 	/**
   219 	/**
   209 	 * Build a Translation_Entry from original string and translation strings,
   220 	 * Build a Translation_Entry from original string and translation strings,
   210 	 * found in a MO file
   221 	 * found in a MO file
   211 	 * 
   222 	 *
   212 	 * @static
   223 	 * @static
   213 	 * @param string $original original string to translate from MO file. Might contain
   224 	 * @param string $original original string to translate from MO file. Might contain
   214 	 * 	0x04 as context separator or 0x00 as singular/plural separator
   225 	 * 	0x04 as context separator or 0x00 as singular/plural separator
   215 	 * @param string $translation translation string from MO file. Might contain
   226 	 * @param string $translation translation string from MO file. Might contain
   216 	 * 	0x00 as a plural translations separator
   227 	 * 	0x00 as a plural translations separator