1 <?php
  2   3   4   5   6   7   8 
  9 
 10 defined('JPATH_PLATFORM') or die;
 11 
 12 use Joomla\Utilities\ArrayHelper;
 13 
 14  15  16  17  18 
 19 class JLanguageHelper
 20 {
 21      22  23  24  25  26  27  28  29  30  31  32 
 33     public static function createLanguageList($actualLanguage, $basePath = JPATH_BASE, $caching = false, $installed = false)
 34     {
 35         $list      = array();
 36         $clientId  = $basePath === JPATH_ADMINISTRATOR ? 1 : 0;
 37         $languages = $installed ? static::getInstalledLanguages($clientId, true) : self::getKnownLanguages($basePath);
 38 
 39         foreach ($languages as $languageCode => $language)
 40         {
 41             $metadata = $installed ? $language->metadata : $language;
 42 
 43             $list[] = array(
 44                 'text'     => isset($metadata['nativeName']) ? $metadata['nativeName'] : $metadata['name'],
 45                 'value'    => $languageCode,
 46                 'selected' => $languageCode === $actualLanguage ? 'selected="selected"' : null,
 47             );
 48         }
 49 
 50         return $list;
 51     }
 52 
 53      54  55  56  57  58  59 
 60     public static function detectLanguage()
 61     {
 62         if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
 63         {
 64             $browserLangs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
 65             $systemLangs = self::getLanguages();
 66 
 67             foreach ($browserLangs as $browserLang)
 68             {
 69                 
 70                 $browserLang = substr($browserLang, 0, strcspn($browserLang, ';'));
 71                 $primary_browserLang = substr($browserLang, 0, 2);
 72 
 73                 foreach ($systemLangs as $systemLang)
 74                 {
 75                     
 76                     $Jinstall_lang = $systemLang->lang_code;
 77 
 78                     if (strlen($Jinstall_lang) < 6)
 79                     {
 80                         if (strtolower($browserLang) == strtolower(substr($systemLang->lang_code, 0, strlen($browserLang))))
 81                         {
 82                             return $systemLang->lang_code;
 83                         }
 84                         elseif ($primary_browserLang == substr($systemLang->lang_code, 0, 2))
 85                         {
 86                             $primaryDetectedLang = $systemLang->lang_code;
 87                         }
 88                     }
 89                 }
 90 
 91                 if (isset($primaryDetectedLang))
 92                 {
 93                     return $primaryDetectedLang;
 94                 }
 95             }
 96         }
 97 
 98         return;
 99     }
100 
101     102 103 104 105 106 107 108 109 
110     public static function getLanguages($key = 'default')
111     {
112         static $languages;
113 
114         if (empty($languages))
115         {
116             
117             if (JFactory::getApplication()->getClientId() == 2)
118             {
119                 $languages[$key] = array();
120                 $knownLangs = self::getKnownLanguages(JPATH_BASE);
121 
122                 foreach ($knownLangs as $metadata)
123                 {
124                     
125                     $obj = new stdClass;
126                     $obj->lang_code = $metadata['tag'];
127                     $languages[$key][] = $obj;
128                 }
129             }
130             else
131             {
132                 $cache = JFactory::getCache('com_languages', '');
133 
134                 if ($cache->contains('languages'))
135                 {
136                     $languages = $cache->get('languages');
137                 }
138                 else
139                 {
140                     $db = JFactory::getDbo();
141                     $query = $db->getQuery(true)
142                         ->select('*')
143                         ->from('#__languages')
144                         ->where('published=1')
145                         ->order('ordering ASC');
146                     $db->setQuery($query);
147 
148                     $languages['default'] = $db->loadObjectList();
149                     $languages['sef'] = array();
150                     $languages['lang_code'] = array();
151 
152                     if (isset($languages['default'][0]))
153                     {
154                         foreach ($languages['default'] as $lang)
155                         {
156                             $languages['sef'][$lang->sef] = $lang;
157                             $languages['lang_code'][$lang->lang_code] = $lang;
158                         }
159                     }
160 
161                     $cache->store($languages, 'languages');
162                 }
163             }
164         }
165 
166         return $languages[$key];
167     }
168 
169     170 171 172 173 174 175 176 177 178 179 180 181 182 
183     public static function getInstalledLanguages($clientId = null, $processMetaData = false, $processManifest = false, $pivot = 'element',
184         $orderField = null, $orderDirection = null)
185     {
186         static $installedLanguages = null;
187 
188         if ($installedLanguages === null)
189         {
190             $cache = JFactory::getCache('com_languages', '');
191 
192             if ($cache->contains('installedlanguages'))
193             {
194                 $installedLanguages = $cache->get('installedlanguages');
195             }
196             else
197             {
198                 $db = JFactory::getDbo();
199 
200                 $query = $db->getQuery(true)
201                     ->select($db->quoteName(array('element', 'name', 'client_id', 'extension_id')))
202                     ->from($db->quoteName('#__extensions'))
203                     ->where($db->quoteName('type') . ' = ' . $db->quote('language'))
204                     ->where($db->quoteName('state') . ' = 0')
205                     ->where($db->quoteName('enabled') . ' = 1');
206 
207                 $installedLanguages = $db->setQuery($query)->loadObjectList();
208 
209                 $cache->store($installedLanguages, 'installedlanguages');
210             }
211         }
212 
213         $clients   = $clientId === null ? array(0, 1) : array((int) $clientId);
214         $languages = array(
215             0 => array(),
216             1 => array(),
217         );
218 
219         foreach ($installedLanguages as $language)
220         {
221             
222             if (!in_array((int) $language->client_id, $clients))
223             {
224                 continue;
225             }
226 
227             $lang = $language;
228 
229             if ($processMetaData || $processManifest)
230             {
231                 $clientPath = (int) $language->client_id === 0 ? JPATH_SITE : JPATH_ADMINISTRATOR;
232                 $metafile   = self::getLanguagePath($clientPath, $language->element) . '/' . $language->element . '.xml';
233 
234                 
235                 if ($processMetaData)
236                 {
237                     try
238                     {
239                         $lang->metadata = self::parseXMLLanguageFile($metafile);
240                     }
241                     
242                     catch (Exception $e)
243                     {
244                         JLog::add(JText::sprintf('JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METAFILE', $language->element, $metafile), JLog::WARNING, 'language');
245 
246                         continue;
247                     }
248 
249                     
250                     if (!is_array($lang->metadata))
251                     {
252                         JLog::add(JText::sprintf('JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METADATA', $language->element, $metafile), JLog::WARNING, 'language');
253 
254                         continue;
255                     }
256                 }
257 
258                 
259                 if ($processManifest)
260                 {
261                     try
262                     {
263                         $lang->manifest = JInstaller::parseXMLInstallFile($metafile);
264                     }
265                     
266                     catch (Exception $e)
267                     {
268                         JLog::add(JText::sprintf('JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METAFILE', $language->element, $metafile), JLog::WARNING, 'language');
269 
270                         continue;
271                     }
272 
273                     
274                     if (!is_array($lang->manifest))
275                     {
276                         JLog::add(JText::sprintf('JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METADATA', $language->element, $metafile), JLog::WARNING, 'language');
277 
278                         continue;
279                     }
280                 }
281             }
282 
283             $languages[$language->client_id][] = $lang;
284         }
285 
286         
287         if ($orderField !== null && $orderDirection !== null)
288         {
289             $orderDirection = strtolower($orderDirection) === 'desc' ? -1 : 1;
290 
291             foreach ($languages as $cId => $language)
292             {
293                 
294                 if (!in_array($cId, $clients))
295                 {
296                     continue;
297                 }
298 
299                 $languages[$cId] = ArrayHelper::sortObjects($languages[$cId], $orderField, $orderDirection, true, true);
300             }
301         }
302 
303         
304         if ($pivot !== null)
305         {
306             foreach ($languages as $cId => $language)
307             {
308                 
309                 if (!in_array($cId, $clients))
310                 {
311                     continue;
312                 }
313 
314                 $languages[$cId] = ArrayHelper::pivot($languages[$cId], $pivot);
315             }
316         }
317 
318         return $clientId !== null ? $languages[$clientId] : $languages;
319     }
320 
321     322 323 324 325 326 327 328 329 330 331 332 333 
334     public static function getContentLanguages($checkPublished = true, $checkInstalled = true, $pivot = 'lang_code', $orderField = null,
335         $orderDirection = null)
336     {
337         static $contentLanguages = null;
338 
339         if ($contentLanguages === null)
340         {
341             $cache = JFactory::getCache('com_languages', '');
342 
343             if ($cache->contains('contentlanguages'))
344             {
345                 $contentLanguages = $cache->get('contentlanguages');
346             }
347             else
348             {
349                 $db = JFactory::getDbo();
350 
351                 $query = $db->getQuery(true)
352                     ->select('*')
353                     ->from($db->quoteName('#__languages'));
354 
355                 $contentLanguages = $db->setQuery($query)->loadObjectList();
356 
357                 $cache->store($contentLanguages, 'contentlanguages');
358             }
359         }
360 
361         $languages = $contentLanguages;
362 
363         
364         if ($checkPublished)
365         {
366             foreach ($languages as $key => $language)
367             {
368                 if ((int) $language->published === 0)
369                 {
370                     unset($languages[$key]);
371                 }
372             }
373         }
374 
375         
376         if ($checkInstalled)
377         {
378             $languages = array_values(array_intersect_key(ArrayHelper::pivot($languages, 'lang_code'), static::getInstalledLanguages(0)));
379         }
380 
381         
382         if ($orderField !== null && $orderDirection !== null)
383         {
384             $languages = ArrayHelper::sortObjects($languages, $orderField, strtolower($orderDirection) === 'desc' ? -1 : 1, true, true);
385         }
386 
387         
388         if ($pivot !== null)
389         {
390             $languages = ArrayHelper::pivot($languages, $pivot);
391         }
392 
393         return $languages;
394     }
395 
396     397 398 399 400 401 402 403 404 405 
406     public static function saveToIniFile($filename, array $strings)
407     {
408         JLoader::register('JFile', JPATH_LIBRARIES . '/joomla/filesystem/file.php');
409 
410         
411         foreach ($strings as $key => $string)
412         {
413             $strings[$key] = addcslashes($string, '"');
414         }
415 
416         
417         $registry = new Joomla\Registry\Registry($strings);
418 
419         return JFile::write($filename, $registry->toString('INI'));
420     }
421 
422     423 424 425 426 427 428 429 430 431 432 433 
434     public static function exists($lang, $basePath = JPATH_BASE)
435     {
436         static $paths = array();
437 
438         
439         if (!$lang)
440         {
441             return false;
442         }
443 
444         $path = $basePath . '/language/' . $lang;
445 
446         
447         if (isset($paths[$path]))
448         {
449             return $paths[$path];
450         }
451 
452         
453         $paths[$path] = is_dir($path);
454 
455         return $paths[$path];
456     }
457 
458     459 460 461 462 463 464 465 466 
467     public static function getMetadata($lang)
468     {
469         $file   = self::getLanguagePath(JPATH_BASE, $lang) . '/' . $lang . '.xml';
470         $result = null;
471 
472         if (is_file($file))
473         {
474             $result = self::parseXMLLanguageFile($file);
475         }
476 
477         if (empty($result))
478         {
479             return;
480         }
481 
482         return $result;
483     }
484 
485     486 487 488 489 490 491 492 493 
494     public static function getKnownLanguages($basePath = JPATH_BASE)
495     {
496         return self::parseLanguageFiles(self::getLanguagePath($basePath));
497     }
498 
499     500 501 502 503 504 505 506 507 508 
509     public static function getLanguagePath($basePath = JPATH_BASE, $language = null)
510     {
511         return $basePath . '/language' . (!empty($language) ? '/' . $language : '');
512     }
513 
514     515 516 517 518 519 520 521 522 
523     public static function parseLanguageFiles($dir = null)
524     {
525         $languages = array();
526 
527         
528         foreach (glob($dir . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $directory)
529         {
530             
531             if (preg_match('#/[a-z]{2,3}-[A-Z]{2}$#', $directory))
532             {
533                 $dirPathParts = pathinfo($directory);
534                 $file         = $directory . '/' . $dirPathParts['filename'] . '.xml';
535 
536                 if (!is_file($file))
537                 {
538                     continue;
539                 }
540 
541                 try
542                 {
543                     
544                     if ($metadata = self::parseXMLLanguageFile($file))
545                     {
546                         $languages = array_replace($languages, array($dirPathParts['filename'] => $metadata));
547                     }
548                 }
549                 catch (RuntimeException $e)
550                 {
551                 }
552             }
553         }
554 
555         return $languages;
556     }
557 
558     559 560 561 562 563 564 565 566 567 
568     public static function parseXMLLanguageFile($path)
569     {
570         if (!is_readable($path))
571         {
572             throw new RuntimeException('File not found or not readable');
573         }
574 
575         
576         $xml = simplexml_load_file($path);
577 
578         if (!$xml)
579         {
580             return;
581         }
582 
583         
584         if ((string) $xml->getName() != 'metafile')
585         {
586             return;
587         }
588 
589         $metadata = array();
590 
591         foreach ($xml->metadata->children() as $child)
592         {
593             $metadata[$child->getName()] = (string) $child;
594         }
595 
596         return $metadata;
597     }
598 }
599