Hawk - PHP documentation
  • Namespace
  • Class
  • Tree

Namespaces

  • Hawk
    • View
      • Plugins

Classes

  • Hawk\App
  • Hawk\ButtonInput
  • Hawk\Cache
  • Hawk\CheckboxInput
  • Hawk\ColorInput
  • Hawk\Conf
  • Hawk\Controller
  • Hawk\Crypto
  • Hawk\DatabaseSessionHandler
  • Hawk\DatetimeInput
  • Hawk\DB
  • Hawk\DBExample
  • Hawk\DeleteInput
  • Hawk\Dialogbox
  • Hawk\EmailInput
  • Hawk\ErrorHandler
  • Hawk\Event
  • Hawk\FileInput
  • Hawk\FileSystem
  • Hawk\FloatInput
  • Hawk\Form
  • Hawk\FormFieldset
  • Hawk\FormInput
  • Hawk\GenericModel
  • Hawk\GifImage
  • Hawk\HawkApi
  • Hawk\HawkUpdater
  • Hawk\HiddenInput
  • Hawk\HtmlInput
  • Hawk\HTTPRequest
  • Hawk\Icon
  • Hawk\Image
  • Hawk\IntegerInput
  • Hawk\ItemList
  • Hawk\ItemListField
  • Hawk\JpegImage
  • Hawk\Lang
  • Hawk\Language
  • Hawk\LeftSidebarTab
  • Hawk\Less
  • Hawk\Logger
  • Hawk\Mail
  • Hawk\MenuItem
  • Hawk\Model
  • Hawk\NoSidebarTab
  • Hawk\NumberInput
  • Hawk\ObjectInput
  • Hawk\Option
  • Hawk\Panel
  • Hawk\PasswordInput
  • Hawk\Permission
  • Hawk\Plugin
  • Hawk\PluginInstaller
  • Hawk\PngImage
  • Hawk\ProfileQuestion
  • Hawk\ProfileQuestionValue
  • Hawk\RadioInput
  • Hawk\Request
  • Hawk\Response
  • Hawk\RightSidebarTab
  • Hawk\Role
  • Hawk\RolePermission
  • Hawk\Route
  • Hawk\Router
  • Hawk\SelectInput
  • Hawk\Session
  • Hawk\Singleton
  • Hawk\SubmitInput
  • Hawk\Tabs
  • Hawk\TextareaInput
  • Hawk\TextInput
  • Hawk\Theme
  • Hawk\TimeInput
  • Hawk\Upload
  • Hawk\User
  • Hawk\View
  • Hawk\View\Plugins\Accordion
  • Hawk\View\Plugins\Button
  • Hawk\View\Plugins\Form
  • Hawk\View\Plugins\Icon
  • Hawk\View\Plugins\Import
  • Hawk\View\Plugins\Panel
  • Hawk\View\Plugins\Tabs
  • Hawk\View\Plugins\Text
  • Hawk\View\Plugins\Uri
  • Hawk\View\Plugins\Widget
  • Hawk\ViewPlugin
  • Hawk\Widget
  • Hawk\WysiwygInput

Traits

  • Hawk\Utils

Exceptions

  • Hawk\AppStopException
  • Hawk\DBExampleException
  • Hawk\DBException
  • Hawk\FileSystemException
  • Hawk\HawkApiException
  • Hawk\ImageException
  • Hawk\MailException
  • Hawk\UploadException
  • Hawk\ViewException
  1 <?php
  2 /**
  3  * Lang.php
  4  *
  5  * @author  Elvyrra SAS
  6  * @license http://rem.mit-license.org/ MIT
  7  */
  8 
  9 namespace Hawk;
 10 
 11 /**
 12  * This class is used to manage translations
 13  *
 14  * @package Core
 15  */
 16 class Lang{
 17 
 18     const DEFAULT_LANGUAGE = 'en';
 19     const ORIGIN_CACHE_FILE = 'lang-file-paths.php';
 20     const CACHE_DIR = 'lang/';
 21     const TRANSLATIONS_DIR = 'admin/translations/';
 22 
 23     /**
 24      * The language keys with their translations
 25      *
 26      * @var array
 27      */
 28     private static $keys = array(),
 29 
 30     /**
 31      * The currently used language
 32      *
 33      * @var string
 34      */
 35     $usedLanguage = '',
 36 
 37     /**
 38      * The cache containing the source files paths
 39      *
 40      * @var array
 41      */
 42     $originCache = array();
 43 
 44     /**
 45      * The plugin of the language file
 46      *
 47      * @var string
 48      */
 49     private $plugin,
 50 
 51     /**
 52      * The language of the language file
 53      *
 54      * @var string
 55      */
 56     $lang,
 57 
 58     /**
 59      * The source file
 60      *
 61      * @var string
 62      */
 63     $originFile,
 64 
 65     /**
 66      * The path of the file containing the custom translations
 67      *
 68      * @var string
 69      */
 70     $translatedFile,
 71 
 72     /**
 73      * The path of the PHP cache file
 74      *
 75      * @var string
 76      */
 77     $cacheFile;
 78 
 79 
 80     /**
 81      * Constructor
 82      *
 83      * @param string $plugin The plugin of the file
 84      * @param string $lang   The language of the file
 85      */
 86     private function __construct($plugin, $lang){
 87         $this->plugin = $plugin;
 88         $this->lang = $lang;
 89 
 90         $this->originFile  = $this->getOriginFile();
 91         $this->translatedFile = $this->getTranslatedFile();
 92         $this->cacheFile = $this->getCacheFile();
 93     }
 94 
 95 
 96     /**
 97      * Find the origin language file
 98      *
 99      * @return string The path of the origin language file
100      */
101     private function getOriginFile(){
102         if(is_file(App::cache()->getCacheFilePath(self::ORIGIN_CACHE_FILE)) && empty(self::$originCache)) {
103             self::$originCache = App::cache()->includeCache(self::ORIGIN_CACHE_FILE);
104         }
105 
106         if(isset(self::$originCache["$this->plugin.$this->lang"])) {
107             // the file is registered in the cache
108             return self::$originCache["$this->plugin.$this->lang"];
109         }
110 
111         // The file is not present in the cache, search it. We use the method Autoload::find that already performs this action
112         foreach(array(MAIN_PLUGINS_DIR, PLUGINS_DIR) as $dir){
113             $files = App::fs()->find($dir, $this->plugin . '.' . $this->lang . '.lang', FileSystem::FIND_FILE_ONLY);
114             if(!empty($files)) {
115                 $file = $files[0];
116 
117                 // register it in the cache
118                 self::$originCache["$this->plugin.$this->lang"] = $file;
119 
120                 return $file;
121             }
122         }
123         return null;
124     }
125 
126 
127     /**
128      * Find the translated file in userfiles directory
129      *
130      * @return string path The path of the file
131      */
132     private function getTranslatedFile(){
133         return USERFILES_PLUGINS_DIR . self::TRANSLATIONS_DIR . $this->plugin . '.' . $this->lang . '.lang';
134     }
135 
136     /**
137      * Find the cache file, containing the PHP version of the language files
138      *
139      * @return string path The path of the cache file
140      */
141     private function getCacheFile(){
142         return self::CACHE_DIR . $this->plugin . '.' . $this->lang . '.php';
143     }
144 
145 
146     /**
147      * Parse a language file
148      *
149      * @param string $file The file to parse
150      *
151      * @return array The language keys of the language file
152      */
153     private function parse($file){
154         return is_file($file) ? parse_ini_string(file_get_contents($file)) : array();
155     }
156 
157 
158     /**
159      * Build the language file as a PHP file contaning an array
160      */
161     private function build(){
162         $build = false;
163 
164         if(!is_file(App::cache()->getCacheFilePath($this->cacheFile))) {
165             $build = true;
166         }
167         elseif(is_file($this->originFile) && !App::cache()->isCached($this->originFile, $this->cacheFile)) {
168             // the origin file is not cached
169             $build = true;
170         }
171         elseif(is_file($this->translatedFile) && !App::cache()->isCached($this->translatedFile, $this->cacheFile)) {
172             // The translated file is not cached
173             $build = true;
174         }
175 
176 
177         if($build) {
178             // Build the cache file
179             $data = array_merge($this->parse($this->originFile), $this->parse($this->translatedFile));
180 
181             App::cache()->save($this->cacheFile, '<?php return ' . var_export($data, true) . ';');
182         }
183     }
184 
185 
186 
187     /**
188      * Load a language file
189      *
190      * @param string $plugin   The plugin to load
191      * @param string $language The language to get the translations in
192      * @param string $force    If set to true, force to reload the translations
193      */
194     private static function load($plugin, $language = LANGUAGE, $force = false){
195         if(!isset(self::$keys[$plugin][$language]) || $force || $language !== self::$usedLanguage) {
196             App::logger()->debug('Reload keys for plugin ' . $plugin . ' and for language ' . $language);
197             self::$keys[$plugin][$language] = array();
198 
199             $instance = new self($plugin, self::DEFAULT_LANGUAGE);
200             $instance->build();
201             self::$keys[$plugin][$language] = App::cache()->includeCache($instance->cacheFile);
202 
203             if($language !== self::DEFAULT_LANGUAGE) {
204                 $instance = new self($plugin, $language);
205                 $instance->build();
206                 $translations = App::cache()->includeCache($instance->cacheFile);
207 
208                 if(!is_array($translations)) {
209                     $translations = array();
210                 }
211 
212                 self::$keys[$plugin][$language] = array_merge(self::$keys[$plugin][$language], $translations);
213             }
214 
215             self::$usedLanguage = $language;
216         }
217     }
218 
219 
220     /**
221      * Get the translations of a language file
222      *
223      * @param string $plugin   The plugin to load
224      * @param string $language The language to get the translations in
225      * @param string $reload   If set to true, force to reload the translations
226      */
227     public static function keys($plugin, $language = LANGUAGE, $reload = false){
228         self::load($plugin, $language, $reload);
229 
230         return self::$keys[$plugin][$language];
231     }
232 
233 
234     /**
235      * Save the cache file containing the origin paths
236      */
237     public static function saveOriginCache(){
238         file_put_contents(CACHE_DIR . self::ORIGIN_CACHE_FILE, '<?php return ' . var_export(self::$originCache, true) . ';');
239     }
240 
241 
242 
243 
244     /**
245      * Check if a language key exists
246      *
247      * @param string $langKey The key to check existence
248      *
249      * @return boolean  True if the language key exists, else false
250      */
251     public static function exists($langKey){
252         list($plugin, $key) = explode('.', $langKey);
253 
254         // get the label(s)
255         self::load($plugin);
256 
257         return isset(self::$keys[$plugin][self::$usedLanguage][$key]);
258     }
259 
260 
261 
262 
263     /**
264      * Get the translation of a language key in the given language
265      *
266      * @param string $langKey  The key to get the translation
267      * @param array  $param    On associative array containing the variables value in the translation
268      * @param mixed  $number   A number describing the singular or plural version of the translation
269      * @param string $language The language to get the translation. By default the current language
270      *
271      * @return string The translation
272      */
273     public static function get($langKey, $param = array(), $number = 0, $language = LANGUAGE){
274         $tmp = explode('.', $langKey);
275         if(count($tmp) != 2) {
276             return $langKey;
277         }
278 
279         list($plugin, $key) = explode('.', $langKey);
280 
281 
282         self::load($plugin, $language);
283 
284         // get the label(s)
285         $labels = isset(self::$keys[$plugin][$language][$key]) ? self::$keys[$plugin][$language][$key] : null;
286 
287         if($labels !== null) {
288             if(is_array($labels)) {
289                 // Multiple values are affected to this key (singular / plural)
290                 if((int) $number > 1) {
291                     // Get the plural of the language key
292                     $label = isset($labels[$number]) ? $labels[$number] : (isset($labels['p']) ? $labels['p'] : $langKey);
293                 }
294                 else{
295                     // Get the singular of the language key
296                     $label = isset($labels[$number]) ? $labels[$number] : (isset($labels['s']) ? $labels['s'] : $langKey);
297                 }
298             }
299             else{
300                 // The language key is a single string
301                 $label = $labels;
302             }
303 
304             if(!empty($param)) {
305                 // Replace parameters into the language key
306                 return str_replace(
307                     array_map(
308                         function ($key) {
309                             return '{'.$key.'}';
310                         }, array_keys($param)
311                     ), $param, $label
312                 );
313             }
314             else
315             return $label;
316         }
317         else{
318             return $langKey;
319         }
320     }
321 
322 
323 
324     /**
325      * Add language keys to Javascript. To add several keys, you can call one time this function, each parameters
326      * being a language key that wille be added to JavaScript
327      *
328      * @param string ...$keys The keys to add
329      *
330      * @deprecated since version 0.7.0, use Controller::addKeysToJavascript instead
331      */
332     public static function addKeysToJavascript(...$keys){
333         $script = "";
334         foreach($keys as $key){
335             list($plugin, $langKey) = explode(".", $key);
336             $script .= "Lang.set('$key', '" . addcslashes(self::get($key), "'") . "');";
337         }
338 
339         App::router()->getCurrentController()->addJavaScriptInline($script);
340     }
341 
342 
343 
344     /**
345      * Get the translations data the user customized on the interface
346      *
347      * @param string $plugin   The plugin name
348      * @param string $language The language tag
349      */
350     public static function getUserTranslations($plugin, $language) {
351         $lang = new self($plugin, $language);
352         $file = $lang->getTranslatedFile();
353         return is_file($file) ? parse_ini_string(file_get_contents($file)) : array();
354     }
355 
356     /**
357      * Save translated data the user customized on the interface
358      *
359      * @param string $plugin   The plugin name
360      * @param string $language The language tag
361      * @param array  $data     The translations to save
362      */
363     public static function saveUserTranslations($plugin, $language, $data) {
364         $lang = new self($plugin, $language);
365         $file = $lang->getTranslatedFile();
366 
367         $lines = array();
368         foreach($data as $key => $value){
369             if(! is_array($value)) {
370                 $lines[] = $key . ' = "' . addcslashes($value, '"') . '"';
371             }
372             else{
373                 foreach($value as $multiplier => $val){
374                     $lines[] = $key . '[' . $multiplier . '] = "' . addcslashes($val, '"') . '"';
375                 }
376             }
377         }
378 
379         $content = implode(PHP_EOL, $lines);
380         $dir = dirname($file);
381         if(!is_dir($dir)) {
382             mkdir($dir, 0755, true);
383         }
384 
385         file_put_contents($file, $content);
386         touch($file, time() + 3);
387     }
388 }
389 
390 /*** Save the language cache ***/
391 Event::on('process-end', function (Event $event) {
392     Lang::saveOriginCache();
393 });
Hawk - PHP documentation API documentation generated by ApiGen