CGettextPoFile.php 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. /**
  3. * CGettextPoFile class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CGettextPoFile represents a PO Gettext message file.
  12. *
  13. * @author Qiang Xue <qiang.xue@gmail.com>
  14. * @package system.i18n.gettext
  15. * @since 1.0
  16. */
  17. class CGettextPoFile extends CGettextFile
  18. {
  19. /**
  20. * Loads messages from a PO file.
  21. * @param string $file file path
  22. * @param string $context message context
  23. * @return array message translations (source message => translated message)
  24. */
  25. public function load($file,$context)
  26. {
  27. $pattern='/(msgctxt\s+"(.*?(?<!\\\\))")?\s+'
  28. .'msgid\s+((?:".*(?<!\\\\)"\s*)+)\s+'
  29. .'msgstr\s+((?:".*(?<!\\\\)"\s*)+)/';
  30. $matches=array();
  31. $n=preg_match_all($pattern,file_get_contents($file),$matches);
  32. $messages=array();
  33. for($i=0; $i<$n; $i++)
  34. {
  35. if($matches[2][$i]===$context)
  36. {
  37. $id=$this->decode($matches[3][$i]);
  38. $message=$this->decode($matches[4][$i]);
  39. $messages[$id]=$message;
  40. }
  41. }
  42. return $messages;
  43. }
  44. /**
  45. * Saves messages to a PO file.
  46. * @param string $file file path
  47. * @param array $messages message translations (message id => translated message).
  48. * Note if the message has a context, the message id must be prefixed with
  49. * the context with chr(4) as the separator.
  50. */
  51. public function save($file,$messages)
  52. {
  53. $content='';
  54. foreach($messages as $id=>$message)
  55. {
  56. if(($pos=strpos($id,chr(4)))!==false)
  57. {
  58. $content.='msgctxt "'.substr($id,0,$pos)."\"\n";
  59. $id=substr($id,$pos+1);
  60. }
  61. $content.='msgid "'.$this->encode($id)."\"\n";
  62. $content.='msgstr "'.$this->encode($message)."\"\n\n";
  63. }
  64. file_put_contents($file,$content);
  65. }
  66. /**
  67. * Encodes special characters in a message.
  68. * @param string $string message to be encoded
  69. * @return string the encoded message
  70. */
  71. protected function encode($string)
  72. {
  73. return str_replace(
  74. array('"',"\n","\t","\r"),
  75. array('\\"',"\\n",'\\t','\\r'),
  76. $string
  77. );
  78. }
  79. /**
  80. * Decodes special characters in a message.
  81. * @param string $string message to be decoded
  82. * @return string the decoded message
  83. */
  84. protected function decode($string)
  85. {
  86. $string=preg_replace(
  87. array('/"\s+"/','/\\\\n/','/\\\\r/','/\\\\t/','/\\\\"/'),
  88. array('',"\n","\r","\t",'"'),
  89. $string
  90. );
  91. return substr(rtrim($string),1,-1);
  92. }
  93. }