]> git.mxchange.org Git - friendica.git/blobdiff - src/Console/PoToPhp.php
Merge pull request #10403 from annando/doc-structure
[friendica.git] / src / Console / PoToPhp.php
index 85dc28cf4d39f4fc8fab7245a710d3045aec5957..35d87165c12c934787414af2a5be672f1921616d 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @copyright Copyright (C) 2020, Friendica
+ * @copyright Copyright (C) 2010-2021, the Friendica project
  *
  * @license GNU AGPL version 3 or any later version
  *
@@ -103,31 +103,27 @@ HELP;
 
                        if (substr($l, 0, 15) == '"Plural-Forms: ') {
                                $match = [];
-                               preg_match("|nplurals=([0-9]*); *plural=(.*)[;\\\\]|", $l, $match);
-                               $cond = str_replace('n', '$n', $match[2]);
+                               preg_match("|nplurals=([0-9]*); *plural=(.*?)[;\\\\]|", $l, $match);
+                               $return = $this->convertCPluralConditionToPhpReturnStatement($match[2]);
                                // define plural select function if not already defined
                                $fnname = 'string_plural_select_' . $lang;
                                $out .= 'if(! function_exists("' . $fnname . '")) {' . "\n";
                                $out .= 'function ' . $fnname . '($n){' . "\n";
                                $out .= '       $n = intval($n);' . "\n";
-                               $out .= '       return ' . $cond . ';' . "\n";
+                               $out .= '       ' . $return . "\n";
                                $out .= '}}' . "\n";
                        }
 
                        if ($k != '' && substr($l, 0, 7) == 'msgstr ') {
-                               if ($ink) {
-                                       $ink = false;
-                                       $out .= '$a->strings["' . $k . '"] = ';
-                               }
-
-                               if ($inv) {
-                                       $out .= '"' . $v . '"';
-                               }
-
                                $v = substr($l, 8, $len - 10);
                                $v = preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $v);
 
-                               $inv = true;
+                               if ($v != '') {
+                                       $out .= '$a->strings["' . $k . '"] = "' . $v . '"';
+                               } else {
+                                       $k = '';
+                                       $ink = false;
+                               }
                        }
 
                        if ($k != "" && substr($l, 0, 7) == 'msgstr[') {
@@ -147,11 +143,13 @@ HELP;
 
                                $match = [];
                                preg_match("|\[([0-9]*)\] (.*)|", $l, $match);
-                               $out .= "\t"
-                                       . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[1])
-                                       . ' => '
-                                       . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[2])
-                                       . ",\n";
+                               if ($match[2] !== '""') {
+                                       $out .= "\t"
+                                               . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[1])
+                                               . ' => '
+                                               . preg_replace_callback($escape_s_exp, [$this, 'escapeDollar'], $match[2])
+                                               . ",\n";
+                               }
                        }
 
                        if (substr($l, 0, 6) == 'msgid_') {
@@ -212,4 +210,82 @@ HELP;
        {
                return str_replace('$', '\$', $match[0]);
        }
+
+       /**
+        * Converts C-style plural condition in .po files to a PHP-style plural return statement
+        *
+        * Adapted from https://github.com/friendica/friendica/issues/9747#issuecomment-769604485
+        * Many thanks to Christian Archer (https://github.com/sunchaserinfo)
+        *
+        * @param string $cond
+        * @return string
+        */
+       private function convertCPluralConditionToPhpReturnStatement(string $cond)
+       {
+               $cond = str_replace('n', '$n', $cond);
+
+               /**
+                * Parses the condition into an array if there's at least a ternary operator, to a string otherwise
+                *
+                * Warning: Black recursive magic
+                *
+                * @param string $string
+                * @param array|string $node
+                */
+               function parse(string $string, &$node = [])
+               {
+                       // Removes extra outward parentheses
+                       if (strpos($string, '(') === 0 && strrpos($string, ')') === strlen($string) - 1) {
+                               $string = substr($string, 1, -1);
+                       }
+
+                       $q = strpos($string, '?');
+                       $s = strpos($string, ':');
+
+                       if ($q === false && $s === false) {
+                               $node = $string;
+                               return;
+                       }
+
+                       if ($q === false || $s < $q) {
+                               list($then, $else) = explode(':', $string, 2);
+                               $node['then'] = $then;
+                               $parsedElse = [];
+                               parse($else, $parsedElse);
+                               $node['else'] = $parsedElse;
+                       } else {
+                               list($if, $thenelse) = explode('?', $string, 2);
+                               $node['if'] = $if;
+                               parse($thenelse, $node);
+                       }
+               }
+
+               /**
+                * Renders the parsed condition tree into a return statement
+                *
+                * Warning: Black recursive magic
+                *
+                * @param $tree
+                * @return string
+                */
+               function render($tree)
+               {
+                       if (is_array($tree)) {
+                               $if = trim($tree['if']);
+                               $then = trim($tree['then']);
+                               $else = render($tree['else']);
+
+                               return "if ({$if}) { return {$then}; } else {$else}";
+                       }
+
+                       $tree = trim($tree);
+
+                       return " { return {$tree}; }";
+               }
+
+               $tree = [];
+               parse($cond, $tree);
+
+               return is_string($tree) ? "return intval({$tree});" : render($tree);
+       }
 }