Autodoc
  • Namespace
  • Class
  • Tree

Namespaces

  • BlueTihi
    • Context
  • Brickrouge
    • Element
      • Nodes
    • Renderer
    • Widget
  • ICanBoogie
    • ActiveRecord
    • AutoConfig
    • CLDR
    • Composer
    • Core
    • Event
    • Exception
    • HTTP
      • Dispatcher
      • Request
    • I18n
      • Translator
    • Mailer
    • Modules
      • Taxonomy
        • Support
      • Thumbnailer
        • Versions
    • Object
    • Operation
      • Dispatcher
    • Prototype
    • Routes
    • Routing
      • Dispatcher
    • Session
  • Icybee
    • ActiveRecord
      • Model
    • ConfigOperation
    • Document
    • EditBlock
    • Element
      • ActionbarContextual
      • ActionbarSearch
      • ActionbarToolbar
    • FormBlock
    • Installer
    • ManageBlock
    • Modules
      • Articles
      • Cache
        • Collection
        • ManageBlock
      • Comments
        • ManageBlock
      • Contents
        • ManageBlock
      • Dashboard
      • Editor
        • Collection
      • Files
        • File
        • ManageBlock
      • Forms
        • Form
        • ManageBlock
      • I18n
      • Images
        • ManageBlock
      • Members
      • Modules
        • ManageBlock
      • Nodes
        • ManageBlock
        • Module
      • Pages
        • BreadcrumbElement
        • LanguagesElement
        • ManageBlock
        • NavigationBranchElement
        • NavigationElement
        • Page
        • PageController
      • Registry
      • Search
      • Seo
      • Sites
        • ManageBlock
      • Taxonomy
        • Terms
          • ManageBlock
        • Vocabulary
          • ManageBlock
      • Users
        • ManageBlock
        • NonceLogin
        • Roles
      • Views
        • ActiveRecordProvider
        • Collection
        • View
    • Operation
      • ActiveRecord
      • Constructor
      • Module
      • Widget
    • Rendering
  • None
  • Patron
  • PHP

Classes

  • FormattedString
  • Helpers
  • Locale
  • NumberFormatter
  • Translator

Functions

  • date_period
  • format_currency
  • format_date
  • format_datetime
  • format_number
  • format_size
  • format_time
  • get_cldr
  • get_language
  • get_locale
  • set_locale
  • t
  1 <?php
  2 
  3 /*
  4  * This file is part of the ICanBoogie package.
  5  *
  6  * (c) Olivier Laviale <olivier.laviale@gmail.com>
  7  *
  8  * For the full copyright and license information, please view the LICENSE
  9  * file that was distributed with this source code.
 10  */
 11 
 12 namespace ICanBoogie\I18n;
 13 
 14 use ICanBoogie\FileCache;
 15 use ICanBoogie\I18n;
 16 use ICanBoogie\Object;
 17 
 18 class Translator extends Object implements \ArrayAccess
 19 {
 20     static private $translators=array();
 21 
 22     /**
 23      * Return the translator for the specified locale.
 24      *
 25      * @param string $id The locale identifier.
 26      *
 27      * @return Translator The translator for the locale.
 28      */
 29     static public function get($id)
 30     {
 31         if (isset(self::$translators[$id]))
 32         {
 33             return self::$translators[$id];
 34         }
 35 
 36         self::$translators[$id] = $translator = new static($id);
 37 
 38         return $translator;
 39     }
 40 
 41     static protected $cache;
 42 
 43     static protected function get_cache()
 44     {
 45         global $core;
 46 
 47         if (!self::$cache)
 48         {
 49             self::$cache = new FileCache
 50             (
 51                 array
 52                 (
 53                     FileCache::T_COMPRESS => true,
 54                     FileCache::T_REPOSITORY => $core->config['repository.cache'] . '/core',
 55                     FileCache::T_SERIALIZE => true
 56                 )
 57             );
 58         }
 59 
 60         return self::$cache;
 61     }
 62 
 63     static public function messages_construct($id)
 64     {
 65         $messages = array();
 66 
 67         foreach (I18n::$load_paths as $path)
 68         {
 69             $filename = $path . DIRECTORY_SEPARATOR . $id . '.php';
 70 
 71             if (!file_exists($filename))
 72             {
 73                 continue;
 74             }
 75 
 76             $messages[] = \ICanBoogie\array_flatten(require $filename);
 77         }
 78 
 79         return count($messages) ? call_user_func_array('array_merge', $messages) : array();
 80     }
 81 
 82     /**
 83      * Translation messages.
 84      *
 85      * @var array
 86      */
 87     protected $messages;
 88 
 89     protected function lazy_get_messages()
 90     {
 91         global $core;
 92 
 93         $messages = array();
 94         $id = $this->id;
 95 
 96         if (isset($core) && $core->config['cache catalogs']) // @TODO-20131007: remove core dependency, use a message provider
 97         {
 98             $messages = self::get_cache()->load('i18n_' . $id, array(__CLASS__, 'messages_construct'), $id);
 99         }
100         else
101         {
102             $messages = self::messages_construct($id);
103         }
104 
105         if ($this->fallback)
106         {
107             $messages += $this->fallback->messages;
108         }
109 
110         return $messages;
111     }
112 
113     /**
114      * Fallback translator.
115      *
116      * @var Translator
117      */
118     protected $fallback;
119 
120     /**
121      * Returns a translator fallback for this translator.
122      *
123      * @return Translator|null The translator fallback for this translator or null if there is
124      * none.
125      */
126     protected function lazy_get_fallback()
127     {
128         list($id, $territory) = explode('-', $this->id) + array(1 => null);
129 
130         if (!$territory && $id == 'en')
131         {
132             return;
133         }
134         else if (!$territory)
135         {
136             $id = 'en';
137         }
138 
139         return self::get($id);
140     }
141 
142     /**
143      * Locale id for this translator.
144      *
145      * @var string
146      */
147     protected $id;
148 
149     /**
150      * Constructor.
151      *
152      * @param string $id Locale identifier
153      */
154     protected function __construct($id)
155     {
156         unset($this->messages);
157         unset($this->fallback);
158 
159         $this->id = $id;
160     }
161 
162     static public $missing = array();
163 
164     /**
165      * Translate a native string in a locale string.
166      *
167      * @param string $native The native string to translate.
168      * @param array $args
169      * @param array $options
170      *
171      * @return string The translated string, or the same native string if no translation could be
172      * found.
173      */
174     public function __invoke($native, array $args=array(), array $options=array())
175     {
176         $native = (string) $native;
177         $messages = $this->messages;
178         $translated = null;
179 
180         $suffix = null;
181 
182         if ($args && array_key_exists(':count', $args))
183         {
184             $count = $args[':count'];
185 
186             if ($count == 0)
187             {
188                 $suffix = '.none';
189             }
190             else if ($count == 1)
191             {
192                 $suffix = '.one';
193             }
194             else
195             {
196                 $suffix = '.other';
197             }
198         }
199 
200         $scope = I18n::get_scope();
201 
202         if (isset($options['scope']))
203         {
204             if ($scope)
205             {
206                 $scope .= '.';
207             }
208 
209             $scope .= is_array($options['scope']) ? implode('.', $options['scope']) : $options['scope'];
210         }
211 
212         $prefix = $scope;
213 
214         while ($scope)
215         {
216             $try = $scope . '.' . $native . $suffix;
217 
218             if (isset($messages[$try]))
219             {
220                 $translated = $messages[$try];
221 
222                 break;
223             }
224 
225             $pos = strpos($scope, '.');
226 
227             if ($pos === false)
228             {
229                 break;
230             }
231 
232             $scope = substr($scope, $pos + 1);
233         }
234 
235         if (!$translated)
236         {
237             if (isset($messages[$native . $suffix]))
238             {
239                 $translated = $messages[$native . $suffix];
240             }
241         }
242 
243         if (!$translated)
244         {
245             self::$missing[] = ($prefix ? $prefix . '.' : '') . $native;
246 
247             if (!empty($options['default']))
248             {
249                 $default = $options['default'];
250 
251                 if (!($default instanceof \Closure))
252                 {
253                     return $default;
254                 }
255 
256                 $native = $default($this, $native, $options, $args) ?: $native;
257             }
258 
259             #
260             # We couldn't find any translation for the native string provided, in order to avoid
261             # another search for the same string, we store the native string as the translation in
262             # the locale messages.
263             #
264 
265             $this->messages[($prefix ? $prefix . '.' : '') . $native] = $native;
266 
267             $translated = $native;
268         }
269 
270         if ($args)
271         {
272             $translated = \ICanBoogie\format($translated, $args);
273         }
274 
275         return $translated;
276     }
277 
278     public function offsetExists($offset)
279     {
280         return isset($this->messages[$offset]);
281     }
282 
283     public function offsetGet($offset)
284     {
285         return isset($this->messages[$offset]) ? $this->messages[$offset] : null;
286     }
287 
288     public function offsetSet($offset, $value)
289     {
290 
291     }
292 
293     public function offsetUnset($offset)
294     {
295 
296     }
297 }
Autodoc API documentation generated by ApiGen 2.8.0