]> git.mxchange.org Git - friendica.git/blob - src/Console/PoToPhp.php
Merge pull request #8271 from MrPetovan/bug/8229-frio-mobile-back-to-top
[friendica.git] / src / Console / PoToPhp.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2020, Friendica
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Console;
23
24 /**
25  * Read a messages.po file and create strings.php in the same directory
26  */
27 class PoToPhp extends \Asika\SimpleConsole\Console
28 {
29         protected $helpOptions = ['h', 'help', '?'];
30
31         const DQ_ESCAPE = "__DQ__";
32
33         protected function getHelp()
34         {
35                 $help = <<<HELP
36 console php2po - Generate a strings.php file from a messages.po file
37 Usage
38         bin/console php2po <path/to/messages.po> [-h|--help|-?] [-v]
39
40 Description
41         Read a messages.po file and create the according strings.php in the same directory
42
43 Options
44         -h|--help|-?  Show help information
45         -v            Show more debug information.
46 HELP;
47                 return $help;
48         }
49
50         protected function doExecute()
51         {
52                 if ($this->getOption('v')) {
53                         $this->out('Class: ' . __CLASS__);
54                         $this->out('Arguments: ' . var_export($this->args, true));
55                         $this->out('Options: ' . var_export($this->options, true));
56                 }
57
58                 if (count($this->args) == 0) {
59                         $this->out($this->getHelp());
60                         return 0;
61                 }
62
63                 if (count($this->args) > 1) {
64                         throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
65                 }
66
67                 $pofile = realpath($this->getArgument(0));
68
69                 if (!file_exists($pofile)) {
70                         throw new \RuntimeException('Supplied file path doesn\'t exist.');
71                 }
72
73                 if (!is_writable(dirname($pofile))) {
74                         throw new \RuntimeException('Supplied directory isn\'t writable.');
75                 }
76
77                 $outfile = dirname($pofile) . DIRECTORY_SEPARATOR . 'strings.php';
78
79                 if (basename(dirname($pofile)) == 'C') {
80                         $lang = 'en';
81                 } else {
82                         $lang = str_replace('-', '_', basename(dirname($pofile)));
83                 }
84
85                 $this->out('Out to ' . $outfile);
86
87                 $out = "<?php\n\n";
88
89                 $infile = file($pofile);
90                 $k = '';
91                 $v = '';
92                 $arr = false;
93                 $ink = false;
94                 $inv = false;
95                 $escape_s_exp = '|[^\\\\]\$[a-z]|';
96
97                 foreach ($infile as $l) {
98                         $l = str_replace('\"', self::DQ_ESCAPE, $l);
99                         $len = strlen($l);
100                         if ($l[0] == "#") {
101                                 $l = "";
102                         }
103
104                         if (substr($l, 0, 15) == '"Plural-Forms: ') {
105                                 $match = [];
106                                 preg_match("|nplurals=([0-9]*); *plural=(.*)[;\\\\]|", $l, $match);
107                                 $cond = str_replace('n', '$n', $match[2]);
108                                 // define plural select function if not already defined
109                                 $fnname = 'string_plural_select_' . $lang;
110                                 $out .= 'if(! function_exists("' . $fnname . '")) {' . "\n";
111                                 $out .= 'function ' . $fnname . '($n){' . "\n";
112                                 $out .= '       $n = intval($n);' . "\n";
113                                 $out .= '       return ' . $cond . ';' . "\n";
114                                 $out .= '}}' . "\n";
115                         }
116
117                         if ($k != '' && substr($l, 0, 7) == 'msgstr ') {
118                                 if ($ink) {
119                                         $ink = false;
120                                         $out .= '$a->strings["' . $k . '"] = ';
121                                 }
122
123                                 if ($inv) {
124                                         $out .= '"' . $v . '"';
125                                 }
126
127                                 $v = substr($l, 8, $len - 10);
128                                 $v = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $v);
129
130                                 $inv = true;
131                         }
132
133                         if ($k != "" && substr($l, 0, 7) == 'msgstr[') {
134                                 if ($ink) {
135                                         $ink = false;
136                                         $out .= '$a->strings["' . $k . '"] = ';
137                                 }
138                                 if ($inv) {
139                                         $inv = false;
140                                         $out .= '"' . $v . '"';
141                                 }
142
143                                 if (!$arr) {
144                                         $arr = true;
145                                         $out .= "[\n";
146                                 }
147
148                                 $match = [];
149                                 preg_match("|\[([0-9]*)\] (.*)|", $l, $match);
150                                 $out .= "\t"
151                                         . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[1])
152                                         . ' => '
153                                         . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[2])
154                                         . ",\n";
155                         }
156
157                         if (substr($l, 0, 6) == 'msgid_') {
158                                 $ink = false;
159                                 $out .= '$a->strings["' . $k . '"] = ';
160                         }
161
162                         if ($ink) {
163                                 $k .= trim($l, "\"\r\n");
164                                 $k = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $k);
165                         }
166
167                         if (substr($l, 0, 6) == 'msgid ') {
168                                 if ($inv) {
169                                         $inv = false;
170                                         $out .= '"' . $v . '"';
171                                 }
172
173                                 if ($k != "") {
174                                         $out .= ($arr) ? "];\n" : ";\n";
175                                 }
176
177                                 $arr = false;
178                                 $k = str_replace("msgid ", "", $l);
179                                 if ($k != '""') {
180                                         $k = trim($k, "\"\r\n");
181                                 } else {
182                                         $k = '';
183                                 }
184
185                                 $k = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $k);
186                                 $ink = true;
187                         }
188
189                         if ($inv && substr($l, 0, 6) != "msgstr") {
190                                 $v .= trim($l, "\"\r\n");
191                                 $v = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $v);
192                         }
193                 }
194
195                 if ($inv) {
196                         $out .= '"' . $v . '"';
197                 }
198
199                 if ($k != '') {
200                         $out .= ($arr ? "];\n" : ";\n");
201                 }
202
203                 $out = str_replace(self::DQ_ESCAPE, '\"', $out);
204                 if (!file_put_contents($outfile, $out)) {
205                         throw new \RuntimeException('Unable to write to ' . $outfile);
206                 }
207
208                 return 0;
209         }
210
211         private function escapeDollar($match)
212         {
213                 return str_replace('$', '\$', $match[0]);
214         }
215 }