wp/wp-includes/pomo/mo.php
changeset 19 3d72ae0968f4
parent 18 be944660c56a
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
    35 		 * Fills up with the entries from MO file $filename
    35 		 * Fills up with the entries from MO file $filename
    36 		 *
    36 		 *
    37 		 * @param string $filename MO file to load
    37 		 * @param string $filename MO file to load
    38 		 * @return bool True if the import from file was successful, otherwise false.
    38 		 * @return bool True if the import from file was successful, otherwise false.
    39 		 */
    39 		 */
    40 		function import_from_file( $filename ) {
    40 		public function import_from_file( $filename ) {
    41 			$reader = new POMO_FileReader( $filename );
    41 			$reader = new POMO_FileReader( $filename );
    42 
    42 
    43 			if ( ! $reader->is_resource() ) {
    43 			if ( ! $reader->is_resource() ) {
    44 				return false;
    44 				return false;
    45 			}
    45 			}
    51 
    51 
    52 		/**
    52 		/**
    53 		 * @param string $filename
    53 		 * @param string $filename
    54 		 * @return bool
    54 		 * @return bool
    55 		 */
    55 		 */
    56 		function export_to_file( $filename ) {
    56 		public function export_to_file( $filename ) {
    57 			$fh = fopen( $filename, 'wb' );
    57 			$fh = fopen( $filename, 'wb' );
    58 			if ( ! $fh ) {
    58 			if ( ! $fh ) {
    59 				return false;
    59 				return false;
    60 			}
    60 			}
    61 			$res = $this->export_to_file_handle( $fh );
    61 			$res = $this->export_to_file_handle( $fh );
    64 		}
    64 		}
    65 
    65 
    66 		/**
    66 		/**
    67 		 * @return string|false
    67 		 * @return string|false
    68 		 */
    68 		 */
    69 		function export() {
    69 		public function export() {
    70 			$tmp_fh = fopen( 'php://temp', 'r+' );
    70 			$tmp_fh = fopen( 'php://temp', 'r+' );
    71 			if ( ! $tmp_fh ) {
    71 			if ( ! $tmp_fh ) {
    72 				return false;
    72 				return false;
    73 			}
    73 			}
    74 			$this->export_to_file_handle( $tmp_fh );
    74 			$this->export_to_file_handle( $tmp_fh );
    78 
    78 
    79 		/**
    79 		/**
    80 		 * @param Translation_Entry $entry
    80 		 * @param Translation_Entry $entry
    81 		 * @return bool
    81 		 * @return bool
    82 		 */
    82 		 */
    83 		function is_entry_good_for_export( $entry ) {
    83 		public function is_entry_good_for_export( $entry ) {
    84 			if ( empty( $entry->translations ) ) {
    84 			if ( empty( $entry->translations ) ) {
    85 				return false;
    85 				return false;
    86 			}
    86 			}
    87 
    87 
    88 			if ( ! array_filter( $entry->translations ) ) {
    88 			if ( ! array_filter( $entry->translations ) ) {
    94 
    94 
    95 		/**
    95 		/**
    96 		 * @param resource $fh
    96 		 * @param resource $fh
    97 		 * @return true
    97 		 * @return true
    98 		 */
    98 		 */
    99 		function export_to_file_handle( $fh ) {
    99 		public function export_to_file_handle( $fh ) {
   100 			$entries = array_filter( $this->entries, array( $this, 'is_entry_good_for_export' ) );
   100 			$entries = array_filter( $this->entries, array( $this, 'is_entry_good_for_export' ) );
   101 			ksort( $entries );
   101 			ksort( $entries );
   102 			$magic                     = 0x950412de;
   102 			$magic                     = 0x950412de;
   103 			$revision                  = 0;
   103 			$revision                  = 0;
   104 			$total                     = count( $entries ) + 1; // All the headers are one entry.
   104 			$total                     = count( $entries ) + 1; // All the headers are one entry.
   105 			$originals_lenghts_addr    = 28;
   105 			$originals_lengths_addr    = 28;
   106 			$translations_lenghts_addr = $originals_lenghts_addr + 8 * $total;
   106 			$translations_lengths_addr = $originals_lengths_addr + 8 * $total;
   107 			$size_of_hash              = 0;
   107 			$size_of_hash              = 0;
   108 			$hash_addr                 = $translations_lenghts_addr + 8 * $total;
   108 			$hash_addr                 = $translations_lengths_addr + 8 * $total;
   109 			$current_addr              = $hash_addr;
   109 			$current_addr              = $hash_addr;
   110 			fwrite(
   110 			fwrite(
   111 				$fh,
   111 				$fh,
   112 				pack(
   112 				pack(
   113 					'V*',
   113 					'V*',
   114 					$magic,
   114 					$magic,
   115 					$revision,
   115 					$revision,
   116 					$total,
   116 					$total,
   117 					$originals_lenghts_addr,
   117 					$originals_lengths_addr,
   118 					$translations_lenghts_addr,
   118 					$translations_lengths_addr,
   119 					$size_of_hash,
   119 					$size_of_hash,
   120 					$hash_addr
   120 					$hash_addr
   121 				)
   121 				)
   122 			);
   122 			);
   123 			fseek( $fh, $originals_lenghts_addr );
   123 			fseek( $fh, $originals_lengths_addr );
   124 
   124 
   125 			// Headers' msgid is an empty string.
   125 			// Headers' msgid is an empty string.
   126 			fwrite( $fh, pack( 'VV', 0, $current_addr ) );
   126 			fwrite( $fh, pack( 'VV', 0, $current_addr ) );
   127 			$current_addr++;
   127 			$current_addr++;
   128 			$originals_table = "\0";
   128 			$originals_table = "\0";
   155 
   155 
   156 		/**
   156 		/**
   157 		 * @param Translation_Entry $entry
   157 		 * @param Translation_Entry $entry
   158 		 * @return string
   158 		 * @return string
   159 		 */
   159 		 */
   160 		function export_original( $entry ) {
   160 		public function export_original( $entry ) {
   161 			// TODO: Warnings for control characters.
   161 			// TODO: Warnings for control characters.
   162 			$exported = $entry->singular;
   162 			$exported = $entry->singular;
   163 			if ( $entry->is_plural ) {
   163 			if ( $entry->is_plural ) {
   164 				$exported .= "\0" . $entry->plural;
   164 				$exported .= "\0" . $entry->plural;
   165 			}
   165 			}
   171 
   171 
   172 		/**
   172 		/**
   173 		 * @param Translation_Entry $entry
   173 		 * @param Translation_Entry $entry
   174 		 * @return string
   174 		 * @return string
   175 		 */
   175 		 */
   176 		function export_translations( $entry ) {
   176 		public function export_translations( $entry ) {
   177 			// TODO: Warnings for control characters.
   177 			// TODO: Warnings for control characters.
   178 			return $entry->is_plural ? implode( "\0", $entry->translations ) : $entry->translations[0];
   178 			return $entry->is_plural ? implode( "\0", $entry->translations ) : $entry->translations[0];
   179 		}
   179 		}
   180 
   180 
   181 		/**
   181 		/**
   182 		 * @return string
   182 		 * @return string
   183 		 */
   183 		 */
   184 		function export_headers() {
   184 		public function export_headers() {
   185 			$exported = '';
   185 			$exported = '';
   186 			foreach ( $this->headers as $header => $value ) {
   186 			foreach ( $this->headers as $header => $value ) {
   187 				$exported .= "$header: $value\n";
   187 				$exported .= "$header: $value\n";
   188 			}
   188 			}
   189 			return $exported;
   189 			return $exported;
   191 
   191 
   192 		/**
   192 		/**
   193 		 * @param int $magic
   193 		 * @param int $magic
   194 		 * @return string|false
   194 		 * @return string|false
   195 		 */
   195 		 */
   196 		function get_byteorder( $magic ) {
   196 		public function get_byteorder( $magic ) {
   197 			// The magic is 0x950412de.
   197 			// The magic is 0x950412de.
   198 
   198 
   199 			// bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565
   199 			// bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565
   200 			$magic_little    = (int) - 1794895138;
   200 			$magic_little    = (int) - 1794895138;
   201 			$magic_little_64 = (int) 2500072158;
   201 			$magic_little_64 = (int) 2500072158;
   212 
   212 
   213 		/**
   213 		/**
   214 		 * @param POMO_FileReader $reader
   214 		 * @param POMO_FileReader $reader
   215 		 * @return bool True if the import was successful, otherwise false.
   215 		 * @return bool True if the import was successful, otherwise false.
   216 		 */
   216 		 */
   217 		function import_from_reader( $reader ) {
   217 		public function import_from_reader( $reader ) {
   218 			$endian_string = MO::get_byteorder( $reader->readint32() );
   218 			$endian_string = MO::get_byteorder( $reader->readint32() );
   219 			if ( false === $endian_string ) {
   219 			if ( false === $endian_string ) {
   220 				return false;
   220 				return false;
   221 			}
   221 			}
   222 			$reader->setEndian( $endian_string );
   222 			$reader->setEndian( $endian_string );
   227 			if ( $reader->strlen( $header ) != 24 ) {
   227 			if ( $reader->strlen( $header ) != 24 ) {
   228 				return false;
   228 				return false;
   229 			}
   229 			}
   230 
   230 
   231 			// Parse header.
   231 			// Parse header.
   232 			$header = unpack( "{$endian}revision/{$endian}total/{$endian}originals_lenghts_addr/{$endian}translations_lenghts_addr/{$endian}hash_length/{$endian}hash_addr", $header );
   232 			$header = unpack( "{$endian}revision/{$endian}total/{$endian}originals_lengths_addr/{$endian}translations_lengths_addr/{$endian}hash_length/{$endian}hash_addr", $header );
   233 			if ( ! is_array( $header ) ) {
   233 			if ( ! is_array( $header ) ) {
   234 				return false;
   234 				return false;
   235 			}
   235 			}
   236 
   236 
   237 			// Support revision 0 of MO format specs, only.
   237 			// Support revision 0 of MO format specs, only.
   238 			if ( 0 != $header['revision'] ) {
   238 			if ( 0 != $header['revision'] ) {
   239 				return false;
   239 				return false;
   240 			}
   240 			}
   241 
   241 
   242 			// Seek to data blocks.
   242 			// Seek to data blocks.
   243 			$reader->seekto( $header['originals_lenghts_addr'] );
   243 			$reader->seekto( $header['originals_lengths_addr'] );
   244 
   244 
   245 			// Read originals' indices.
   245 			// Read originals' indices.
   246 			$originals_lengths_length = $header['translations_lenghts_addr'] - $header['originals_lenghts_addr'];
   246 			$originals_lengths_length = $header['translations_lengths_addr'] - $header['originals_lengths_addr'];
   247 			if ( $originals_lengths_length != $header['total'] * 8 ) {
   247 			if ( $originals_lengths_length != $header['total'] * 8 ) {
   248 				return false;
   248 				return false;
   249 			}
   249 			}
   250 
   250 
   251 			$originals = $reader->read( $originals_lengths_length );
   251 			$originals = $reader->read( $originals_lengths_length );
   252 			if ( $reader->strlen( $originals ) != $originals_lengths_length ) {
   252 			if ( $reader->strlen( $originals ) != $originals_lengths_length ) {
   253 				return false;
   253 				return false;
   254 			}
   254 			}
   255 
   255 
   256 			// Read translations' indices.
   256 			// Read translations' indices.
   257 			$translations_lenghts_length = $header['hash_addr'] - $header['translations_lenghts_addr'];
   257 			$translations_lengths_length = $header['hash_addr'] - $header['translations_lengths_addr'];
   258 			if ( $translations_lenghts_length != $header['total'] * 8 ) {
   258 			if ( $translations_lengths_length != $header['total'] * 8 ) {
   259 				return false;
   259 				return false;
   260 			}
   260 			}
   261 
   261 
   262 			$translations = $reader->read( $translations_lenghts_length );
   262 			$translations = $reader->read( $translations_lengths_length );
   263 			if ( $reader->strlen( $translations ) != $translations_lenghts_length ) {
   263 			if ( $reader->strlen( $translations ) != $translations_lengths_length ) {
   264 				return false;
   264 				return false;
   265 			}
   265 			}
   266 
   266 
   267 			// Transform raw data into set of indices.
   267 			// Transform raw data into set of indices.
   268 			$originals    = $reader->str_split( $originals, 8 );
   268 			$originals    = $reader->str_split( $originals, 8 );
   309 		 *  0x04 as context separator or 0x00 as singular/plural separator
   309 		 *  0x04 as context separator or 0x00 as singular/plural separator
   310 		 * @param string $translation translation string from MO file. Might contain
   310 		 * @param string $translation translation string from MO file. Might contain
   311 		 *  0x00 as a plural translations separator
   311 		 *  0x00 as a plural translations separator
   312 		 * @return Translation_Entry Entry instance.
   312 		 * @return Translation_Entry Entry instance.
   313 		 */
   313 		 */
   314 		function &make_entry( $original, $translation ) {
   314 		public function &make_entry( $original, $translation ) {
   315 			$entry = new Translation_Entry();
   315 			$entry = new Translation_Entry();
   316 			// Look for context, separated by \4.
   316 			// Look for context, separated by \4.
   317 			$parts = explode( "\4", $original );
   317 			$parts = explode( "\4", $original );
   318 			if ( isset( $parts[1] ) ) {
   318 			if ( isset( $parts[1] ) ) {
   319 				$original       = $parts[1];
   319 				$original       = $parts[1];
   333 
   333 
   334 		/**
   334 		/**
   335 		 * @param int $count
   335 		 * @param int $count
   336 		 * @return string
   336 		 * @return string
   337 		 */
   337 		 */
   338 		function select_plural_form( $count ) {
   338 		public function select_plural_form( $count ) {
   339 			return $this->gettext_select_plural_form( $count );
   339 			return $this->gettext_select_plural_form( $count );
   340 		}
   340 		}
   341 
   341 
   342 		/**
   342 		/**
   343 		 * @return int
   343 		 * @return int
   344 		 */
   344 		 */
   345 		function get_plural_forms_count() {
   345 		public function get_plural_forms_count() {
   346 			return $this->_nplurals;
   346 			return $this->_nplurals;
   347 		}
   347 		}
   348 	}
   348 	}
   349 endif;
   349 endif;