Wordpress 2.8
[autoinstalls/wordpress.git] / wp-includes / pomo / po.php
1 <?php
2 /**
3  * Class for working with PO files
4  *
5  * @version $Id: po.php 33 2009-02-16 09:33:39Z nbachiyski $
6  * @package pomo
7  * @subpackage po
8  */
9
10 require_once dirname(__FILE__) . '/translations.php';
11
12 define('PO_MAX_LINE_LEN', 79);
13
14 ini_set('auto_detect_line_endings', 1);
15
16 /**
17  * Routines for working with PO files
18  */
19 class PO extends Translations {
20
21
22         /**
23          * Exports headers to a PO entry
24          *
25          * @return string msgid/msgstr PO entry for this PO file headers, doesn't contain newline at the end
26          */
27         function export_headers() {
28                 $header_string = '';
29                 foreach($this->headers as $header => $value) {
30                         $header_string.= "$header: $value\n";
31                 }
32                 $poified = PO::poify($header_string);
33                 return rtrim("msgid \"\"\nmsgstr $poified");
34         }
35
36         /**
37          * Exports all entries to PO format
38          *
39          * @return string sequence of mgsgid/msgstr PO strings, doesn't containt newline at the end
40          */
41         function export_entries() {
42                 //TODO sorting
43                 return implode("\n\n", array_map(array('PO', 'export_entry'), $this->entries));
44         }
45
46         /**
47          * Exports the whole PO file as a string
48          *
49          * @param bool $include_headers whether to include the headers in the export
50          * @return string ready for inclusion in PO file string for headers and all the enrtries
51          */
52         function export($include_headers = true) {
53                 $res = '';
54                 if ($include_headers) {
55                         $res .= $this->export_headers();
56                         $res .= "\n\n";
57                 }
58                 $res .= $this->export_entries();
59                 return $res;
60         }
61
62         /**
63          * Same as {@link export}, but writes the result to a file
64          *
65          * @param string $filename where to write the PO string
66          * @param bool $include_headers whether to include tje headers in the export
67          * @return bool true on success, false on error
68          */
69         function export_to_file($filename, $include_headers = true) {
70                 $fh = fopen($filename, 'w');
71                 if (false === $fh) return false;
72                 $export = $this->export($include_headers);
73                 $res = fwrite($fh, $export);
74                 if (false === $res) return false;
75                 return fclose($fh);
76         }
77
78
79         /**
80          * Formats a string in PO-style
81          *
82          * @static
83          * @param string $string the string to format
84          * @return string the poified string
85          */
86         function poify($string) {
87                 $quote = '"';
88                 $slash = '\\';
89                 $newline = "\n";
90                 $tab = "\t";
91
92                 $replaces = array(
93                         "$slash"        => "$slash$slash",
94                         "$tab"          => '\t',
95                         "$quote"        => "$slash$quote",
96                 );
97                 $string = str_replace(array_keys($replaces), array_values($replaces), $string);
98
99                 $po = array();
100                 foreach (explode($newline, $string) as $line) {
101                         $po[] = wordwrap($line, PO_MAX_LINE_LEN - 2, " $quote$newline$quote");
102                 }
103                 $po = $quote.implode("${slash}n$quote$newline$quote", $po).$quote;
104                 // add empty string on first line for readbility
105                 if (false !== strpos($po, $newline)) {
106                         $po = "$quote$quote$newline$po";
107                 }
108                 // remove empty strings
109                 $po = str_replace("$newline$quote$quote", '', $po);
110                 return $po;
111         }
112
113         /**
114          * Inserts $with in the beginning of every new line of $string and
115          * returns the modified string
116          *
117          * @static
118          * @param string $string prepend lines in this string
119          * @param string $with prepend lines with this string
120          */
121         function prepend_each_line($string, $with) {
122                 $php_with = var_export($with, true);
123                 $lines = explode("\n", $string);
124                 // do not prepend the string on the last empty line, artefact by explode
125                 if ("\n" == substr($string, -1)) unset($lines[count($lines) - 1]);
126                 $res = implode("\n", array_map(create_function('$x', "return $php_with.\$x;"), $lines));
127                 // give back the empty line, we ignored above
128                 if ("\n" == substr($string, -1)) $res .= "\n";
129                 return $res;
130         }
131
132         /**
133          * Prepare a text as a comment -- wraps the lines and prepends #
134          * and a special character to each line
135          *
136          * @access private
137          * @param string $text the comment text
138          * @param string $char character to denote a special PO comment,
139          *      like :, default is a space
140          */
141         function comment_block($text, $char=' ') {
142                 $text = wordwrap($text, PO_MAX_LINE_LEN - 3);
143                 return PO::prepend_each_line($text, "#$char ");
144         }
145
146         /**
147          * Builds a string from the entry for inclusion in PO file
148          *
149          * @static
150          * @param object &$entry the entry to convert to po string
151          * @return string|bool PO-style formatted string for the entry or
152          *      false if the entry is empty
153          */
154         function export_entry(&$entry) {
155                 if (is_null($entry->singular)) return false;
156                 $po = array();
157                 if (!empty($entry->translator_comments)) $po[] = PO::comment_block($entry->translator_comments);
158                 if (!empty($entry->extracted_comments)) $po[] = PO::comment_block($entry->extracted_comments, '.');
159                 if (!empty($entry->references)) $po[] = PO::comment_block(implode(' ', $entry->references), ':');
160                 if (!empty($entry->flags)) $po[] = PO::comment_block(implode("\n", $entry->flags), ',');
161                 if (!is_null($entry->context)) $po[] = 'msgctxt '.PO::poify($entry->context);
162                 $po[] = 'msgid '.PO::poify($entry->singular);
163                 if (!$entry->is_plural) {
164                         $translation = empty($entry->translations)? '' : $entry->translations[0];
165                         $po[] = 'msgstr '.PO::poify($translation);
166                 } else {
167                         $po[] = 'msgid_plural '.PO::poify($entry->plural);
168                         $translations = empty($entry->translations)? array('', '') : $entry->translations;
169                         foreach($translations as $i => $translation) {
170                                 $po[] = "msgstr[$i] ".PO::poify($translation);
171                         }
172                 }
173                 return implode("\n", $po);
174         }
175
176 }
177 ?>