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