]> source.dussan.org Git - nextcloud-server.git/commitdiff
Create plural functions on the fly
authorJakob Sack <mail@jakobsack.de>
Thu, 1 Aug 2013 19:18:18 +0000 (21:18 +0200)
committerJakob Sack <mail@jakobsack.de>
Thu, 1 Aug 2013 19:25:14 +0000 (21:25 +0200)
lib/l10n.php
lib/l10n/string.php

index d24717a23a2793a075aa765bb2446023f6589398..208fa930c99bd419d5c002b699af23024735c9f7 100644 (file)
@@ -55,9 +55,14 @@ class OC_L10N{
        private $translations = array();
 
        /**
-        * Plural forms
+        * Plural forms (string)
         */
-       private $plural_forms = "";
+       private $plural_form_string;
+
+       /**
+        * Plural forms (function)
+        */
+       private $plural_form_function = null;
 
        /**
         * Localization
@@ -144,7 +149,7 @@ class OC_L10N{
                                        }
                                }
                                if(isset($PLURAL_FORMS)) {
-                                       $this->plural_forms = $PLURAL_FORMS;
+                                       $this->plural_form_string = $PLURAL_FORMS;
                                }
                        }
 
@@ -161,6 +166,66 @@ class OC_L10N{
                }
        }
 
+       /**
+        * @brief Creates a function that The constructor
+        * @param $app the app requesting l10n
+        * @param $lang default: null Language
+        * @returns OC_L10N-Object
+        *
+        * If language is not set, the constructor tries to find the right
+        * language.
+        *
+        * Parts of the code is copied from Habari:
+        * https://github.com/habari/system/blob/master/classes/locale.php
+        */
+       protected function createPluralFormFunction($string){
+               if(preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s*plural=(.*)$/u', $string, $matches)) {
+                       // sanitize
+                       $nplurals = preg_replace( '/[^0-9]/', '', $matches[1] );
+                       $plural = preg_replace( '#[^n0-9:\(\)\?\|\&=!<>+*/\%-]#', '', $matches[2] );
+
+                       $body = str_replace(
+                               array( 'plural', 'n', '$n$plurals', ),
+                               array( '$plural', '$n', '$nplurals', ),
+                               'nplurals='. $nplurals . '; plural=' . $plural
+                       );
+
+                       // add parens
+                       // important since PHP's ternary evaluates from left to right
+                       $body .= ';';
+                       $res = '';
+                       $p = 0;
+                       for($i = 0; $i < strlen($body); $i++) {
+                               $ch = $body[$i];
+                               switch ( $ch ) {
+                               case '?':
+                                       $res .= ' ? (';
+                                       $p++;
+                                       break;
+                               case ':':
+                                       $res .= ') : (';
+                                       break;
+                               case ';':
+                                       $res .= str_repeat( ')', $p ) . ';';
+                                       $p = 0;
+                                       break;
+                               default:
+                                       $res .= $ch;
+                               }
+                       }
+
+                       $body = $res . 'return ($plural>=$nplurals?$nplurals-1:$plural);';
+                       return create_function('$n', $body);
+               }
+               else {
+                       // default: one plural form for all cases but n==1 (english)
+                       return create_function(
+                               '$n',
+                               '$nplurals=2;$plural=($n==1?0:1);return ($plural>=$nplurals?$nplurals-1:$plural);'
+                       );
+               }
+       }
+
        /**
         * @brief Translating
         * @param $text String The text we need a translation for
@@ -239,14 +304,28 @@ class OC_L10N{
        }
 
        /**
-        * @brief getPluralForms
+        * @brief getPluralFormString
         * @returns Fetches the gettext "Plural-Forms"-string
         *
         * Returns a string like "nplurals=2; plural=(n != 1);"
         */
-       public function getPluralForms() {
+       public function getPluralFormString() {
                $this->init();
-               return $this->plural_forms;
+               return $this->plural_form_string;
+       }
+
+       /**
+        * @brief getPluralFormFunction
+        * @returns returns the plural form function
+        *
+        * returned function accepts the argument $n
+        */
+       public function getPluralFormString() {
+               $this->init();
+               if(is_null($this->plural_form_function)) {
+                       $this->plural_form_function = createPluralFormFunction($this->plural_form_string);
+               }
+               return $this->plural_form_function;
        }
 
        /**
index 5b9dbaee8a2c4bdbb4417c955d2a680841c0307a..8d83f1f61fb4eb5b354f550f00ad40749e8748ad 100644 (file)
@@ -23,7 +23,7 @@ class OC_L10N_String{
                $text = $this->text;
                if(array_key_exists($this->text, $translations)) {
                        if(is_array($translations[$this->text])) {
-                               $id = $localizations["selectplural"]( $count );
+                               $id = $l10n->getPluralFormFunction()( $count );
                                $text = $translations[$this->text][$id];
                        }
                        else{