Merge pull request #4633 from friendica/fabrixxm-36rc-patch-2
[friendica.git/.git] / src / Core / Console / PoToPhp.php
1 <?php\r
2 \r
3 namespace Friendica\Core\Console;\r
4 \r
5 /**\r
6  * Read a messages.po file and create strings.php in the same directory\r
7  *\r
8  * @author Hypolite Petovan <mrpetovan@gmail.com>\r
9  */\r
10 class PoToPhp extends \Asika\SimpleConsole\Console\r
11 {\r
12         protected $helpOptions = ['h', 'help', '?'];\r
13 \r
14         const DQ_ESCAPE = "__DQ__";\r
15 \r
16         protected function getHelp()\r
17         {\r
18                 $help = <<<HELP\r
19 console php2po - Generate a strings.php file from a messages.po file\r
20 Usage\r
21         bin/console php2po <path/to/messages.po> [-h|--help|-?] [-v]\r
22 \r
23 Description\r
24         Read a messages.po file and create the according strings.php in the same directory\r
25 \r
26 Options\r
27         -h|--help|-?  Show help information\r
28         -v            Show more debug information.\r
29 HELP;\r
30                 return $help;\r
31         }\r
32 \r
33         protected function doExecute()\r
34         {\r
35                 if ($this->getOption('v')) {\r
36                         $this->out('Class: ' . __CLASS__);\r
37                         $this->out('Arguments: ' . var_export($this->args, true));\r
38                         $this->out('Options: ' . var_export($this->options, true));\r
39                 }\r
40 \r
41                 if (count($this->args) == 0) {\r
42                         $this->out($this->getHelp());\r
43                         return 0;\r
44                 }\r
45 \r
46                 if (count($this->args) > 1) {\r
47                         throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');\r
48                 }\r
49 \r
50                 $a = get_app();\r
51 \r
52                 $pofile = realpath($this->getArgument(0));\r
53 \r
54                 if (!file_exists($pofile)) {\r
55                         throw new \RuntimeException('Supplied file path doesn\'t exist.');\r
56                 }\r
57 \r
58                 if (!is_writable(dirname($pofile))) {\r
59                         throw new \RuntimeException('Supplied directory isn\'t writable.');\r
60                 }\r
61 \r
62                 $outfile = dirname($pofile) . DIRECTORY_SEPARATOR . 'strings.php';\r
63 \r
64                 if (strstr($outfile, 'util')) {\r
65                         $lang = 'en';\r
66                 } else {\r
67                         $lang = str_replace('-', '_', basename(dirname($pofile)));\r
68                 }\r
69 \r
70                 $this->out('Out to ' . $outfile);\r
71 \r
72                 $out = "<?php\n\n";\r
73 \r
74                 $infile = file($pofile);\r
75                 $k = '';\r
76                 $v = '';\r
77                 $arr = false;\r
78                 $ink = false;\r
79                 $inv = false;\r
80                 $escape_s_exp = '|[^\\\\]\$[a-z]|';\r
81 \r
82                 foreach ($infile as $l) {\r
83                         $l = str_replace('\"', self::DQ_ESCAPE, $l);\r
84                         $len = strlen($l);\r
85                         if ($l[0] == "#") {\r
86                                 $l = "";\r
87                         }\r
88 \r
89                         if (substr($l, 0, 15) == '"Plural-Forms: ') {\r
90                                 $match = [];\r
91                                 preg_match("|nplurals=([0-9]*); *plural=(.*)[;\\\\]|", $l, $match);\r
92                                 $cond = str_replace('n', '$n', $match[2]);\r
93                                 // define plural select function if not already defined\r
94                                 $fnname = 'string_plural_select_' . $lang;\r
95                                 $out .= 'if(! function_exists("' . $fnname . '")) {' . "\n";\r
96                                 $out .= 'function ' . $fnname . '($n){' . "\n";\r
97                                 $out .= '       return ' . $cond . ';' . "\n";\r
98                                 $out .= '}}' . "\n";\r
99                         }\r
100 \r
101                         if ($k != "" && substr($l, 0, 7) == 'msgstr ') {\r
102                                 if ($ink) {\r
103                                         $ink = false;\r
104                                         $out .= '$a->strings["' . $k . '"] = ';\r
105                                 }\r
106 \r
107                                 if ($inv) {\r
108                                         $inv = false;\r
109                                         $out .= '"' . $v . '"';\r
110                                 }\r
111 \r
112                                 $v = substr($l, 8, $len - 11);\r
113                                 $v = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $v);\r
114 \r
115                                 $inv = true;\r
116                         }\r
117                         if ($k != "" && substr($l, 0, 7) == 'msgstr[') {\r
118                                 if ($ink) {\r
119                                         $ink = false;\r
120                                         $out .= '$a->strings["' . $k . '"] = ';\r
121                                 }\r
122                                 if ($inv) {\r
123                                         $inv = false;\r
124                                         $out .= '"' . $v . '"';\r
125                                 }\r
126 \r
127                                 if (!$arr) {\r
128                                         $arr = True;\r
129                                         $out .= "[\n";\r
130                                 }\r
131                                 $match = [];\r
132                                 preg_match("|\[([0-9]*)\] (.*)|", $l, $match);\r
133                                 $out .= "\t"\r
134                                         . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[1])\r
135                                         . ' => '\r
136                                         . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[2])\r
137                                         . ",\n";\r
138                         }\r
139 \r
140                         if (substr($l, 0, 6) == 'msgid_') {\r
141                                 $ink = false;\r
142                                 $out .= '$a->strings["' . $k . '"] = ';\r
143                         }\r
144 \r
145                         if ($ink) {\r
146                                 $k .= trim($l, "\"\r\n");\r
147                                 $k = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $k);\r
148                         }\r
149 \r
150                         if (substr($l, 0, 6) == 'msgid ') {\r
151                                 if ($inv) {\r
152                                         $inv = false;\r
153                                         $out .= '"' . $v . '"';\r
154                                 }\r
155                                 if ($k != "") {\r
156                                         $out .= ($arr) ? "];\n" : ";\n";\r
157                                 }\r
158                                 $arr = false;\r
159                                 $k = str_replace("msgid ", "", $l);\r
160                                 if ($k != '""') {\r
161                                         $k = trim($k, "\"\r\n");\r
162                                 } else {\r
163                                         $k = '';\r
164                                 }\r
165 \r
166                                 $k = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $k);\r
167                                 $ink = true;\r
168                         }\r
169 \r
170                         if ($inv && substr($l, 0, 6) != "msgstr") {\r
171                                 $v .= trim($l, "\"\r\n");\r
172                                 $v = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $v);\r
173                         }\r
174                 }\r
175 \r
176                 if ($inv) {\r
177                         $inv = false;\r
178                         $out .= '"' . $v . '"';\r
179                 }\r
180 \r
181                 if ($k != '') {\r
182                         $out .= ($arr ? "];\n" : ";\n");\r
183                 }\r
184 \r
185                 $out = str_replace(self::DQ_ESCAPE, '\"', $out);\r
186                 if (!file_put_contents($outfile, $out)) {\r
187                         throw new \RuntimeException('Unable to write to ' . $outfile);\r
188                 }\r
189 \r
190                 return 0;\r
191         }\r
192 \r
193         private function escapeDollar($match)\r
194         {\r
195                 return str_replace('$', '\$', $match[0]);\r
196         }\r
197 }\r