+ private function createPluralSelectFunctionString(string $pluralForms, string $lang): string
+ {
+ $return = $this->convertCPluralConditionToPhpReturnStatement(
+ $pluralForms
+ );
+
+ $fnname = 'string_plural_select_' . $lang;
+ $out = 'if(! function_exists("' . $fnname . '")) {' . "\n";
+ $out .= 'function ' . $fnname . '($n){' . "\n";
+ $out .= ' $n = intval($n);' . "\n";
+ $out .= ' ' . $return . "\n";
+ $out .= '}}' . "\n";
+
+ return $out;
+ }
+
+ private static function escapePhpString($string): string
+ {
+ return "'" . strtr($string, ['\'' => '\\\'']) . "'";
+ }
+
+ /**
+ * 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);
+
+ $tree = [];
+ self::parse($cond, $tree);
+
+ return is_string($tree) ? "return intval({$tree});" : self::render($tree);
+ }
+
+ /**
+ * 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
+ */
+ private static function parse(string $string, &$node = [])
+ {
+ // Removes extra outward parentheses
+ if (strpos($string, '(') === 0 && strrpos($string, ')') === strlen($string) - 1) {
+ $string = substr($string, 1, -1);