| [ Index ] | PHP Cross Reference of Mambo 4.6.5 |
|
| [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @version 0.9 4 * @author Carlos Souza 5 * @copyright Copyright (c) 2005 Carlos Souza <csouza@web-sense.net> 6 * @package PHPGettext 7 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) 8 * @link http://phpgettext.web-sense.net 9 */ 10 defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); 11 12 define('_MODE_MO_', 'mo'); 13 define('_MODE_PO_', 'po'); 14 define('_MODE_POT_','pot'); 15 define('_MODE_GLO_','go'); 16 17 require_once(dirname(__FILE__).'/phpgettext.message.php'); 18 class PHPGettext_Catalog 19 { 20 var $mode = _MODE_MO_; 21 var $name = ''; 22 var $path = ''; 23 var $lang = 'en'; 24 var $charset = 'utf-8'; 25 var $category = 'LC_MESSAGES'; 26 var $comments = array(); 27 var $headers = array(); 28 var $strings = array(); 29 function PHPGettext_Catalog($name, $path) 30 { 31 $this->name = trim($name); 32 $this->path = trim($path); 33 } 34 35 function load() 36 { 37 switch ($this->mode) 38 { 39 case _MODE_MO_: 40 return $this->_readMO(); 41 break; 42 case _MODE_PO_: 43 return $this->_readPO(); 44 break; 45 case _MODE_POT_: 46 return $this->_readPO(); 47 break; 48 case _MODE_GLO_: 49 $this->mode = _MODE_PO_; 50 $this->lang = 'glossary'; 51 return $this->_readPO(); 52 break; 53 default: 54 trigger_error('Unrecognized mode in '.__CLASS__.'->'.__FUNCTION__, E_USER_ERROR); 55 return false; 56 break; 57 } 58 } 59 60 function save() 61 { 62 63 $langdir = $this->path.DIRECTORY_SEPARATOR.$this->lang; 64 if (!is_dir($langdir)) { 65 $this->createdir($langdir.DIRECTORY_SEPARATOR.$this->category); 66 } 67 68 switch ($this->mode) 69 { 70 case _MODE_MO_: 71 return $this->_writeMO(); 72 break; 73 case _MODE_PO_: 74 $this->setRevisionDate(); 75 return $this->_writePO(); 76 case _MODE_POT_: 77 return $this->_writePO(); 78 break; 79 case _MODE_GLO_: 80 $this->mode = _MODE_PO_; 81 $this->lang = 'glossary'; 82 return $this->_writePO(); 83 break; 84 default: 85 trigger_error('Unrecognized mode in '.__CLASS__.'->'.__FUNCTION__, E_USER_ERROR); 86 return false; 87 break; 88 } 89 } 90 91 92 function filename() 93 { 94 $return = $this->path.DIRECTORY_SEPARATOR; 95 $return .= !empty($this->lang) ? $this->lang.DIRECTORY_SEPARATOR : ''; 96 $return .= (!empty($this->category) && $this->mode == _MODE_MO_) ? $this->category.DIRECTORY_SEPARATOR : ''; 97 $return .= $this->name.'.'.$this->mode; 98 return $return; 99 } 100 101 function createdir($path) 102 { 103 if (!file_exists($path)) 104 { 105 // The directory doesn't exist. Recurse, passing in the parent 106 // directory so that it gets created. 107 $this->createdir(dirname($path)); 108 mkdir($path, 0777); 109 } 110 } 111 112 function setRevisionDate() 113 { 114 $this->headers['PO-Revision-Date'] = date('Y-m-d G:iO'); 115 } 116 117 function setComments($comments) 118 { 119 $comments = trim($comments); 120 if (is_string($comments)) { 121 $comments = explode("\n", $comments); 122 if (is_array($comments)) { 123 foreach ($comments as $comment) { 124 if (strpos($comment, '#') == 1) { 125 $this->comments .= $comment."\n"; 126 } 127 } 128 } 129 } 130 } 131 132 function setHeaders($headers) 133 { 134 if (!is_array($headers)) { 135 return false; 136 } 137 foreach ($headers as $key => $value) { 138 $this->headers[$key] = $value; 139 } 140 } 141 142 function setproperty($property, $value = null) { 143 $return = $this->$property; 144 $this->$property = $value; 145 return $return; 146 } 147 function getproperty($property) { 148 return $this->$property; 149 } 150 151 function addentry($msgid, $msgid_plural=null, $msgstr=null, $comments=array()) 152 { 153 $entry = new PHPGettext_Message($msgid, $msgid_plural); 154 if (!is_null($msgstr)) $entry->setmsgstr($msgstr); 155 if (!empty($comments)) $entry->setcomments($comments); 156 $this->strings[$msgid] = $entry; 157 } 158 159 function translate(&$translations) 160 { 161 $n = count($this->strings); 162 for ($i=0;$i<$n;$i++){ 163 if (!empty($translations[$this->strings[$i]->msgid])){ 164 $this->strings[$i]->setmsgstr ($translations[$this->strings[$i]->msgid]); 165 } 166 } 167 } 168 169 function merge(&$glossary) 170 { 171 foreach ($this->strings as $msgid => $string){ 172 if (!$glossary[$string->msgid]){ 173 $glossary[$string->msgid] = $string; 174 }else{ 175 $glossary[$string->msgid]->comments = array_merge($glossary[$string->msgid]->comments,$string->comments); 176 $glossary[$string->msgid]->comments = array_unique($glossary[$string->msgid]->comments); 177 } 178 } 179 $n = count($glossary); 180 unset($this->strings); 181 foreach ($glossary as $msgid => $string){ 182 $this->addentry($msgid, $string->msgid_plural, $string->msgstr, $string->comments); 183 } 184 } 185 186 function _writePO() 187 { 188 $file = $this->filename(); 189 190 // open PO file 191 if (!is_resource($res = @fopen($file, 'a'))) { 192 trigger_error("Cannot create '$file'. ", E_USER_WARNING); 193 return false; 194 } 195 // lock PO file exclusively 196 if (!@flock($res, LOCK_EX)) { 197 @fclose($res); 198 trigger_error("Cannot lock '$file'. ", E_USER_WARNING); 199 return false; 200 } 201 @ftruncate($res,0); 202 // write comments 203 if (count($this->comments > 0)) { 204 foreach ($this->comments as $line) { 205 fwrite($res, trim($line)."\n"); 206 } 207 } 208 // write meta info 209 if (count($this->headers > 0)) { 210 $header = 'msgid ""' . "\nmsgstr " . '""' . "\n"; 211 foreach ($this->headers as $k => $v) { 212 $header .= '"' . $k . ': ' . $v . '\n"' . "\n"; 213 } 214 fwrite($res, $header . "\n"); 215 } 216 217 // write strings 218 if (count($this->strings > 0)) { 219 foreach ($this->strings as $string) { 220 fwrite($res, $string->toString()); 221 } 222 } 223 //done 224 @flock($res, LOCK_UN); 225 @fclose($res); 226 return true; 227 } 228 229 function _readPO() 230 { 231 $file = $this->filename(); 232 if (!is_readable($file)) { 233 trigger_error('Gettext Catalog '.$this->filename().' not found', E_USER_WARNING); 234 return false; 235 } 236 // load file 237 if (!$data = @file($file)) { 238 trigger_error('Gettext Catalog '.$this->filename().' not found', E_USER_WARNING); 239 return false; 240 } 241 $count = 0; 242 $comments = ''; 243 $is_fuzzy = false; 244 $nplural = false; 245 246 // get all strings 247 foreach ($data as $line) { 248 // comments 249 if (strncmp($line, "#", 1) == 0) { 250 if ($count < 1) { 251 $this->comments[] = $line; 252 } else { 253 if (strncmp($line, "#,", 2) == 0 && preg_match('/fuzzy/', $line)) { 254 unset($line); 255 $is_fuzzy = true; 256 } 257 if (isset($line)) { 258 $comments[] = $line; 259 } 260 } 261 }// msgid 262 elseif (preg_match('/^msgid\s*"(.*)"\s*|^msgid_plural\s*"(.*)"\s*/s', $line, $matches)) { 263 if (preg_match('/^msgid_plural\s*/s', $line, $arr)) { 264 $nplural = true; 265 $strings[$count]['msgid_plural'] = $matches[2]; 266 } else { 267 $count++; 268 $strings[$count]['comments'] = isset($comments) ? $comments : ''; 269 $strings[$count]['msgid'] = ''; 270 $strings[$count]['msgid_plural'] = ''; 271 $strings[$count]['msgstr'] = ''; 272 $strings[$count]['is_fuzzy'] = $is_fuzzy; 273 if (!empty($matches[1])) { 274 $strings[$count]['msgid'] = $matches[1]; 275 } 276 unset($msgstr); 277 unset($comments); 278 $nplural = false; 279 $is_fuzzy = false; 280 281 } 282 } // msgstr 283 elseif (preg_match('/^msgstr\s*"(.*)"\s*|^msgstr\[[0-9]\]\s*"(.*)"\s*/s', $line, $matches)) { 284 $msgstr = true; 285 if ($nplural) { 286 $strings[$count]['msgstr'][] = isset($matches[2]) ? $matches[2] : ''; 287 } else { 288 $strings[$count]['msgstr'] = $matches[1]; 289 } 290 } // multiline msgid or msgstr 291 elseif (preg_match('/^"(.*)"\s*$/s', $line, $matches)) { 292 // headers 293 if (isset($msgstr) && $count == 1) { 294 list($key, $value) = explode(':', $matches[1], 2); 295 $this->headers[$key] = $value; 296 } 297 elseif (isset($msgstr) && $count > 1) { 298 $strings[$count]['msgstr'] .= $matches[1]; 299 } 300 else { // msgid 301 $strings[$count]['msgid'] .= $matches[1]; 302 } 303 } 304 } 305 306 // load the strings 307 array_shift($strings); 308 for ($a=0; $a < count($strings); $a++) { 309 $this->strings[$a] = new PHPGettext_Message($strings[$a]['msgid'], $strings[$a]['msgid_plural']); 310 $this->strings[$a]->setmsgstr($strings[$a]['msgstr']); 311 $this->strings[$a]->setfuzzy($strings[$a]['is_fuzzy']); 312 $this->strings[$a]->setcomments($strings[$a]['comments']); 313 } 314 return true; 315 } 316 317 function _writeMO() 318 { 319 $file = $this->filename(); 320 321 // open MO file 322 if (!is_resource($res = @fopen($file, 'w'))) { 323 trigger_error("Cannot create '$file'. ", E_USER_WARNING); 324 } 325 // lock MO file exclusively 326 if (!@flock($res, LOCK_EX)) { 327 @fclose($res); 328 trigger_error("Cannot lock '$file'. ", E_USER_WARNING); 329 } 330 331 // get the headers 332 $headers = ""; 333 foreach ($this->headers as $key => $val) { 334 $headers .= $key . ': ' . $val . "\n"; 335 } 336 $strings[] = array('msgid' => "", 'msgstr' => $headers); 337 338 // don't write fuzzy entries 339 foreach ($this->strings as $message) { 340 if (!$message->is_fuzzy) { 341 $strings[] = array('msgid' => $message->msgid,'msgid_plural' => $message->msgid_plural, 'msgstr' => $message->msgstr); 342 } 343 344 } 345 346 $count = count($strings); 347 fwrite($res, pack('L', (int) 0x950412de)); // magic number 348 fwrite($res, pack('L', 0)); // revision 0 349 fwrite($res, pack('L', $count)); // N - number of strings 350 $offset = 28; 351 fwrite($res, pack('L', $offset)); // O - offset of table with original strings 352 $offset += ($count * 8); 353 fwrite($res, pack('L', $offset)); // T - offset of table with translation strings 354 fwrite($res, pack('L', 0)); // S - size of hashing table (set to 0 to omit the table) 355 $offset += ($count * 8); 356 fwrite($res, pack('L', $offset)); // H - offset of hashing table 357 358 // offsets for original strings 359 for ($a=0; $a<$count; $a++) { 360 if (isset($strings[$a]['msgid_plural'])) { // plurals 361 $strings[$a]['msgid'] = $strings[$a]['msgid'] ."\0".$strings[$a]['msgid_plural']; 362 } 363 $len = strlen($strings[$a]['msgid']); 364 fwrite($res, pack('L', $len)); 365 fwrite($res, pack('L', $offset)); 366 $offset += $len + 1; 367 } 368 369 // offsets for translated strings 370 for ($a=0; $a<$count; $a++) { 371 if (is_array($strings[$a]['msgstr'])) { // plurals 372 $strings[$a]['msgstr'] = implode("\0", $strings[$a]['msgstr']); 373 } 374 $len = strlen($strings[$a]['msgstr']); 375 fwrite($res, pack('L', $len)); 376 fwrite($res, pack('L', $offset)); 377 $offset += $len + 1; 378 } 379 380 // write original strings 381 foreach ($strings as $str) { 382 fwrite($res, $str['msgid'] . "\0"); 383 } 384 // write translated strings 385 foreach ($strings as $str) { 386 fwrite($res, $str['msgstr'] . "\0"); 387 } 388 // done 389 @flock($res, LOCK_UN); 390 @fclose($res); 391 return true; 392 } 393 394 395 function _readMO() 396 { 397 $file = $this->filename(); 398 if (!file_exists($file)) return false; 399 400 // read in data file completely 401 $f = fopen($file, "rb"); 402 $data = fread($f, 1<<20); 403 fclose($f); 404 405 // extract header fields and check file magic 406 if ($data) { 407 $header = substr($data, 0, 20); 408 $header = unpack("L1magic/L1version/L1count/L1o_msg/L1o_trn", $header); 409 extract($header); 410 $magicNumber = substr(dechex($magic),-8); 411 if (($magicNumber == "950412de") && ($version == 0)) { 412 // fetch all strings 413 for ($a=0; $a<$count; $a++) { 414 // msgid 415 $r = unpack("L1len/L1offs", substr($data, $o_msg + $a * 8, 8)); 416 $msgid = substr($data, $r["offs"], $r["len"]); 417 unset($msgid_plural); 418 if (strpos($msgid, "\0")) { // plurals 419 list($msgid, $msgid_plural) = explode("\0", $msgid); 420 } 421 // msgstr 422 $r = unpack("L1len/L1offs", substr($data, $o_trn + $a * 8, 8)); 423 $msgstr = substr($data, $r["offs"], $r["len"]); 424 if (isset($msgid_plural)) { // plurals 425 $msgstr = explode("\0", $msgstr); 426 } 427 $strings[$a]['msgid'] = $msgid; 428 $strings[$a]['msgstr'] = $msgstr; 429 $strings[$a]['msgid_plural'] = isset($msgid_plural) ? $msgid_plural : ''; 430 } 431 if (!empty($strings[0]['msgstr'])){ // header 432 $str = explode("\n", $strings[0]['msgstr']); 433 foreach ($str as $s){ 434 if (!empty($s)) { 435 @list($key, $value) = explode(':', $s, 2); 436 $this->headers[$key] = $value; 437 } 438 } 439 } 440 // load the strings 441 array_shift($strings); 442 for ($a=0; $a < count($strings); $a++) { 443 $this->strings[$a] = new PHPGettext_Message($strings[$a]['msgid'], $strings[$a]['msgid_plural']); 444 $this->strings[$a]->setmsgstr($strings[$a]['msgstr']); 445 } 446 return true; 447 } 448 } 449 return false; 450 } 451 452 453 } 454 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Feb 8 00:05:01 2012 | Cross-referenced by PHPXref 0.7 |
| Mambo API: Mambo is Free software released under the GNU/General Public License, Version 2 |