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