15
15
16
16
/**
17
17
* @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
18
+ * @copyright Copyright (c) 2012, Clemens Tolboom
18
19
*/
19
20
class PoFileLoader extends ArrayLoader implements LoaderInterface
20
21
{
@@ -41,6 +42,36 @@ public function load($resource, $locale, $domain = 'messages')
41
42
/**
42
43
* Parses portable object (PO) format.
43
44
*
45
+ * From http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
46
+ * we should be able to parse files having:
47
+ *
48
+ * white-space
49
+ * # translator-comments
50
+ * #. extracted-comments
51
+ * #: reference...
52
+ * #, flag...
53
+ * #| msgid previous-untranslated-string
54
+ * msgid untranslated-string
55
+ * msgstr translated-string
56
+ *
57
+ * extra or different lines are:
58
+ *
59
+ * #| msgctxt previous-context
60
+ * #| msgid previous-untranslated-string
61
+ * msgctxt context
62
+ *
63
+ * #| msgid previous-untranslated-string-singular
64
+ * #| msgid_plural previous-untranslated-string-plural
65
+ * msgid untranslated-string-singular
66
+ * msgid_plural untranslated-string-plural
67
+ * msgstr[0] translated-string-case-0
68
+ * ...
69
+ * msgstr[N] translated-string-case-n
70
+ *
71
+ * The definition states:
72
+ * - white-space and comments are optional.
73
+ * - msgid "" that an empty singleline defines a header.
74
+ *
44
75
* This parser sacrifices some features of the reference implementation the
45
76
* differences to that implementation are as follows.
46
77
* - No support for comments spanning multiple lines.
@@ -69,20 +100,14 @@ private function parse($resource)
69
100
$ line = trim ($ line );
70
101
71
102
if ($ line === '' ) {
72
- if (is_array ($ item ['translated ' ])) {
73
- $ messages [$ item ['ids ' ]['singular ' ]] = stripslashes ($ item ['translated ' ][0 ]);
74
- if (isset ($ item ['ids ' ]['plural ' ])) {
75
- $ plurals = array ();
76
- foreach ($ item ['translated ' ] as $ plural => $ translated ) {
77
- $ plurals [] = sprintf ('{%d} %s ' , $ plural , $ translated );
78
- }
79
- $ messages [$ item ['ids ' ]['plural ' ]] = stripcslashes (implode ('| ' , $ plurals ));
80
- }
81
- } elseif (!empty ($ item ['ids ' ]['singular ' ])) {
82
- $ messages [$ item ['ids ' ]['singular ' ]] = stripslashes ($ item ['translated ' ]);
83
- }
103
+ // Whitespace indicated current item is done
104
+ $ this ->addMessage ($ messages , $ item );
84
105
$ item = $ defaults ;
85
106
} elseif (substr ($ line , 0 , 7 ) === 'msgid " ' ) {
107
+ // We start a new msg so save previous
108
+ // TODO: this fails when comments or contexts are added
109
+ $ this ->addMessage ($ messages , $ item );
110
+ $ item = $ defaults ;
86
111
$ item ['ids ' ]['singular ' ] = substr ($ line , 7 , -1 );
87
112
} elseif (substr ($ line , 0 , 8 ) === 'msgstr " ' ) {
88
113
$ item ['translated ' ] = substr ($ line , 8 , -1 );
@@ -103,8 +128,41 @@ private function parse($resource)
103
128
}
104
129
105
130
}
131
+ // save last item
132
+ $ this ->addMessage ($ messages , $ item );
106
133
fclose ($ stream );
107
134
108
135
return array_filter ($ messages );
109
136
}
137
+
138
+ /**
139
+ * Save a translation item to the messeages.
140
+ *
141
+ * A .po file could contain by error missing plural indexes. We need to
142
+ * fix these before saving them.
143
+ *
144
+ * @param array $messages
145
+ * @param array $item
146
+ */
147
+ private function addMessage (array &$ messages , array $ item )
148
+ {
149
+ if (is_array ($ item ['translated ' ])) {
150
+ $ messages [$ item ['ids ' ]['singular ' ]] = stripslashes ($ item ['translated ' ][0 ]);
151
+ if (isset ($ item ['ids ' ]['plural ' ])) {
152
+ $ plurals = $ item ['translated ' ];
153
+ // PO are by definition indexed so sort by index.
154
+ ksort ($ plurals );
155
+ // Make sure every index is filled.
156
+ end ($ plurals );
157
+ $ count = key ($ plurals );
158
+ // Fill missing spots with '-'.
159
+ $ empties = array_fill (0 , $ count +1 , '- ' );
160
+ $ plurals += $ empties ;
161
+ ksort ($ plurals );
162
+ $ messages [$ item ['ids ' ]['plural ' ]] = stripcslashes (implode ('| ' , $ plurals ));
163
+ }
164
+ } elseif (!empty ($ item ['ids ' ]['singular ' ])) {
165
+ $ messages [$ item ['ids ' ]['singular ' ]] = stripslashes ($ item ['translated ' ]);
166
+ }
167
+ }
110
168
}
0 commit comments