20 declare(strict_types=1);
56 $il_absolute_path = realpath(__DIR__ .
"/../../../../");
57 $this->lang_path = $il_absolute_path .
"/lang";
58 $this->cust_lang_path = $il_absolute_path .
"/Customizing/global/lang";
68 public function txt(
string $a_topic,
string $a_default_lang_fallback_mod =
''): string
72 if (empty($a_topic)) {
76 $translation = $this->text[$a_topic] ??
'';
79 $pos = strpos($translation, $this->comment_separator);
83 $translation = substr($translation, 0, $pos);
86 if ($translation ===
"") {
87 $log->writeLanguageLog($a_topic, $this->lang_key);
88 return "-" . $a_topic .
"-";
105 if (empty($a_lang_keys)) {
106 $a_lang_keys = array();
109 if (empty($a_local_keys)) {
110 $a_local_keys = array();
117 foreach ($a_lang_keys as $lang_key) {
122 if (in_array($lang_key, $a_local_keys,
true) && is_dir($this->cust_lang_path)) {
131 if (!array_key_exists($lang_key, $db_langs)) {
132 if (in_array($lang_key, $a_local_keys,
true)) {
133 $itype =
"installed_local";
135 $itype =
"installed";
137 $lid = $ilDB->nextId(
"object_data");
138 $query =
"INSERT INTO object_data " .
139 "(obj_id,type,title,description,owner,create_date,last_update) " .
142 $ilDB->quote($lid,
"integer") .
"," .
143 $ilDB->quote(
"lng",
"text") .
"," .
144 $ilDB->quote($lang_key,
"text") .
"," .
145 $ilDB->quote($itype,
"text") .
"," .
146 $ilDB->quote(
"-1",
"integer") .
"," .
150 $ilDB->manipulate($query);
157 foreach ($db_langs as
$key => $val) {
158 if (!in_array(
$key, $err_lang,
true)) {
159 if (in_array(
$key, $a_lang_keys,
true)) {
160 if (in_array(
$key, $a_local_keys,
true)) {
161 $ld =
"installed_local";
165 $query =
"UPDATE object_data SET " .
166 "description = " . $ilDB->quote($ld,
"text") .
", " .
167 "last_update = " . $ilDB->quote(gmdate(
"Y-m-d H:i:s"),
"timestamp") .
" " .
168 "WHERE obj_id = " . $ilDB->quote($val[
"obj_id"],
"integer") .
" " .
169 "AND type = " . $ilDB->quote(
"lng",
"text");
170 $ilDB->manipulate($query);
174 if (strpos($val[
"status"],
"installed") === 0) {
175 $query =
"UPDATE object_data SET " .
176 "description = " . $ilDB->quote(
"not_installed",
"text") .
", " .
177 "last_update = " . $ilDB->quote(gmdate(
"Y-m-d H:i:s"),
"timestamp") .
" " .
178 "WHERE obj_id = " . $ilDB->quote($val[
"obj_id"],
"integer") .
" " .
179 "AND type = " . $ilDB->quote(
"lng",
"text");
180 $ilDB->manipulate($query);
186 return ($err_lang) ?:
true;
199 $query =
"SELECT * FROM object_data " .
200 "WHERE type = " . $ilDB->quote(
"lng",
"text") .
" " .
201 "AND " . $ilDB->like(
"description",
"text",
"installed%");
202 $r = $ilDB->query($query);
204 while ($row = $ilDB->fetchObject(
$r)) {
205 $arr[] = $row->title;
219 $query =
"SELECT * FROM object_data " .
220 "WHERE type = " . $ilDB->quote(
"lng",
"text") .
" " .
221 "AND description = " . $ilDB->quote(
"installed_local",
"text");
222 $r = $ilDB->query($query);
224 while ($row = $ilDB->fetchObject(
$r)) {
225 $arr[] = $row->title;
240 $query =
"SELECT * FROM object_data " .
241 "WHERE type = " . $ilDB->quote(
"lng",
"text");
242 $r = $ilDB->query($query);
244 while ($row = $ilDB->fetchObject(
$r)) {
245 $arr[$row->title][
"obj_id"] = $row->obj_id;
246 $arr[$row->title][
"status"] = $row->description;
265 $scopeExtension =
"";
267 if (
$scope ===
"global") {
270 $scopeExtension =
"." .
$scope;
283 $lang_file =
"ilias_" . $a_lang_key .
".lang" . $scopeExtension;
286 if (!is_file($lang_file)) {
292 if (!$content = $this->
cut_header(file($lang_file))) {
298 foreach ($content as
$key => $val) {
299 $separated = explode($this->separator, trim($val));
300 $num = count($separated);
326 foreach ($content as
$key => $val) {
327 if (trim($val) ===
"<!-- language file start -->") {
328 return array_slice($content,
$key + 1);
339 protected function flushLanguage(
string $a_lang_key,
string $a_mode =
"all"): void
343 self::_deleteLangData($a_lang_key, ($a_mode ===
"keep_local"));
345 if ($a_mode ===
"all") {
346 $ilDB->manipulate(
"DELETE FROM lng_modules WHERE lang_key = " .
347 $ilDB->quote($a_lang_key,
"text"));
356 public static function _deleteLangData(
string $a_lang_key,
bool $a_keep_local_change): void
360 if (!$a_keep_local_change) {
361 $ilDB->manipulate(
"DELETE FROM lng_data WHERE lang_key = " .
362 $ilDB->quote($a_lang_key,
"text"));
364 $ilDB->manipulate(
"DELETE FROM lng_data WHERE lang_key = " .
365 $ilDB->quote($a_lang_key,
"text") .
366 " AND local_change IS NULL");
377 public function getLocalChanges(
string $a_lang_key,
string $a_min_date =
"",
string $a_max_date =
""): array
381 if ($a_min_date ===
"") {
382 $a_min_date =
"1980-01-01 00:00:00";
384 if ($a_max_date ===
"") {
385 $a_max_date =
"2200-01-01 00:00:00";
389 "SELECT * FROM lng_data WHERE lang_key = %s " .
390 "AND local_change >= %s AND local_change <= %s",
391 $ilDB->quote($a_lang_key,
"text"),
392 $ilDB->quote($a_min_date,
"timestamp"),
393 $ilDB->quote($a_max_date,
"timestamp")
395 $result = $ilDB->query(
$q);
399 $changes[$row[
"module"]][$row[
"identifier"]] = $row[
"value"];
416 $lang_array = array();
418 $scopeExtension =
"";
420 if (
$scope ===
"global") {
423 $scopeExtension =
"." .
$scope;
435 $lang_file =
"ilias_" . $lang_key .
".lang" . $scopeExtension;
438 if (is_file($lang_file)) {
441 $lang_array[
"common"] = [];
444 if ($content = $this->
cut_header(file($lang_file))) {
448 } elseif (
$scope ===
"local") {
452 $change_date = date(
"Y-m-d H:i:s", time());
453 $min_date = date(
"Y-m-d H:i:s", filemtime($lang_file));
457 $query_check =
false;
458 $query =
"INSERT INTO lng_data (module,identifier,lang_key,value,local_change,remarks) VALUES ";
459 foreach ($content as
$key => $val) {
465 $separated = explode($this->separator, trim($val));
468 $pos = strpos($separated[2], $this->comment_separator);
470 if ($pos !==
false) {
472 $separated[2] = substr($separated[2], 0, $pos);
476 if (isset($local_changes[$separated[0]])) {
477 $local_value = $local_changes[$separated[0]][$separated[1]] ??
"";
483 if ($local_value !==
"" && $local_value !== $separated[2]) {
485 $lang_array[$separated[0]][$separated[1]] = $local_value;
488 } elseif (
$scope ===
"local") {
489 if ($local_value !==
"") {
491 $lang_array[$separated[0]][$separated[1]] = $local_value;
497 "(%s,%s,%s,%s,%s,%s),",
498 $ilDB->quote($separated[0],
"text"),
499 $ilDB->quote($separated[1],
"text"),
500 $ilDB->quote($lang_key,
"text"),
501 $ilDB->quote($separated[2],
"text"),
502 $ilDB->quote($change_date,
"timestamp"),
503 $ilDB->quote($separated[3] ?? null,
"text")
506 $lang_array[$separated[0]][$separated[1]] = $separated[2];
508 $query = rtrim($query,
",") .
" ON DUPLICATE KEY UPDATE value=VALUES(value),remarks=VALUES(remarks);";
510 $ilDB->manipulate($query);
514 $query =
"INSERT INTO lng_modules (module, lang_key, lang_array) VALUES ";
515 $modules_to_delete = [];
516 foreach ($lang_array as $module => $lang_arr) {
518 $q =
"SELECT * FROM lng_modules WHERE " .
519 " lang_key = " . $ilDB->quote($lang_key,
"text") .
520 " AND module = " . $ilDB->quote($module,
"text");
521 $set = $ilDB->query(
$q);
522 $row = $ilDB->fetchAssoc($set);
523 $arr2 = unserialize($row[
"lang_array"], [
"allowed_classes" =>
false]);
524 if (is_array($arr2)) {
525 $lang_arr = array_merge($arr2, $lang_arr);
530 $ilDB->quote($module,
"text"),
531 $ilDB->quote($lang_key,
"text"),
532 $ilDB->quote(serialize($lang_arr),
"clob"),
534 $modules_to_delete[] = $module;
537 $inModulesToDelete = $ilDB->in(
'module', $modules_to_delete,
false,
'text');
538 $ilDB->manipulate(sprintf(
539 "DELETE FROM lng_modules WHERE lang_key = %s AND $inModulesToDelete",
540 $ilDB->quote($lang_key,
"text")
543 $query = rtrim($query,
",") .
";";
544 $ilDB->manipulate($query);
556 $local_langs = array();
557 if (is_dir($this->cust_lang_path)) {
558 $d = dir($this->cust_lang_path);
560 chdir($this->cust_lang_path);
563 while ($entry =
$d->read()) {
564 if (is_file($entry) && (preg_match(
"~(^ilias_.{2}\.lang.local$)~", $entry))) {
565 $lang_key = substr($entry, 6, 2);
581 $d = dir($this->lang_path);
583 chdir($this->lang_path);
585 $installableLanguages = [];
587 while ($entry =
$d->read()) {
588 if (is_file($entry) && (preg_match(
"~(^ilias_.{2}\.lang$)~", $entry))) {
589 $lang_key = substr($entry, 6, 2);
596 return $installableLanguages;
606 $this->db = &$a_db_handler;
getInstallableLanguages()
Return installable languages.
flushLanguage(string $a_lang_key, string $a_mode="all")
remove language data from database $a_lang_key language key $a_mode "all" or "keep_local" ...
string $comment_separator
getLocalChanges(string $a_lang_key, string $a_min_date="", string $a_max_date="")
get locally changed language entries $a_lang_key language key $a_min_date minimum change date "yyyy-m...
__construct(string $a_lang_key)
txt(string $a_topic, string $a_default_lang_fallback_mod='')
gets the text for a given topic
language handling for setup
cut_header(array $content)
Remove *.lang header information from '$content'.
checkLanguage(string $a_lang_key, string $scope="")
validate the logical structure of a lang-file
installLanguages(array $a_lang_keys, array $a_local_keys)
install languages
getInstalledLanguages()
get already installed languages (in db)
getInstalledLocalLanguages()
get already installed local languages (in db)
loadLanguageModule(string $a_module)
getAvailableLanguages()
get already registered languages (in db)
getLocalLanguages()
Searches for the existence of *.lang.local files.
insertLanguage(string $lang_key, string $scope="")
insert language data from file in database
setDbHandler(ilDBInterface $a_db_handler)
set db handler object object db handler Return true on success
static _deleteLangData(string $a_lang_key, bool $a_keep_local_change)
Delete languge data.