ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilObjLanguageDBAccess.php
Go to the documentation of this file.
1<?php declare(strict_types=1);
2
20{
21 protected $ilDB;
22 protected $key;
23 protected $content;
24 protected $scope;
25 protected $local_changes;
26 protected $change_date = null;
27 protected $separator;
29
30 public function __construct(ilDBInterface $ilDB, string $key, array $content, array $local_changes, string $scope = "", string $separator = "#:#", string $comment_separator = "###")
31 {
32 $this->ilDB = $ilDB;
33 $this->key = $key;
34 $this->content = $content;
35 $this->local_changes = $local_changes;
36 $this->scope = $scope;
37 if ($scope === "local") {
38 $this->change_date = date("Y-m-d H:i:s", time());
39 }
40 $this->separator = $separator;
41 $this->comment_separator = $comment_separator;
42 }
43
44 public function insertLangEntries(string $lang_file): array
45 {
46 // initialize the array for updating lng_modules below
47 $lang_array = array();
48 $lang_array["common"] = array();
49
50 $double_checker = [];
51 $query_check = false;
52 $query = "INSERT INTO lng_data (module,identifier,lang_key,value,local_change,remarks) VALUES ";
53 foreach ($this->content as $val) {
54 // split the line of the language file
55 // [0]: module
56 // [1]: identifier
57 // [2]: value
58 // [3]: comment (optional)
59 $separated = explode($this->separator, trim($val));
60 $pos = strpos($separated[2], $this->comment_separator);
61 if ($pos !== false) {
62 $separated[3] = substr($separated[2], $pos + strlen($this->comment_separator));
63 $separated[2] = substr($separated[2], 0, $pos);
64 }
65
66 // check if the value has a local change
67 $local_value = $this->local_changes[$separated[0]][$separated[1]] ?? "";
68
69 if (empty($this->scope)) {
70 // import of a global language file
71 if ($local_value !== "" && $local_value !== $separated[2]) {
72 // keep an existing and different local value
73 $lang_array[$separated[0]][$separated[1]] = $local_value;
74 continue;
75 }
76 } elseif ($this->scope === "local") {
77 // import of a local language file
78 if ($local_value !== "") {
79 // keep a locally changed value that is newer than the file
80 $lang_array[$separated[0]][$separated[1]] = $local_value;
81 continue;
82 }
83 }
84 if ($double_checker[$separated[0]][$separated[1]][$this->key] ?? false) {
85 global $DIC;
87 $ilErr = $DIC["ilErr"];
88 $ilErr->raiseError(
89 "Duplicate Language Entry in $lang_file:\n$val",
90 $ilErr->MESSAGE
91 );
92 }
93 $double_checker[$separated[0]][$separated[1]][$this->key] = true;
94
95 $query .= sprintf(
96 "(%s,%s,%s,%s,%s,%s),",
97 $this->ilDB->quote($separated[0], "text"),
98 $this->ilDB->quote($separated[1], "text"),
99 $this->ilDB->quote($this->key, "text"),
100 $this->ilDB->quote($separated[2], "text"),
101 $this->ilDB->quote($this->change_date, "timestamp"),
102 $this->ilDB->quote($separated[3] ?? null, "text")
103 );
104 $query_check = true;
105 $lang_array[$separated[0]][$separated[1]] = $separated[2];
106 }
107 $query = rtrim($query, ",") . " ON DUPLICATE KEY UPDATE value=VALUES(value),remarks=VALUES(remarks);";
108 if ($query_check) {
109 $this->ilDB->manipulate($query);
110 }
111
112 return $lang_array;
113 }
114
115 public function replaceLangModules(array $lang_array): void
116 {
117 // avoid flushing the whole cache (see mantis #28818)
118 ilCachedLanguage::getInstance($this->key)->deleteInCache();
119
120 $query = "INSERT INTO lng_modules (module, lang_key, lang_array) VALUES ";
121 $modules_to_delete = [];
122 foreach ($lang_array as $module => $lang_arr) {
123 if ($this->scope === "local") {
124 $q = "SELECT * FROM lng_modules WHERE " .
125 " lang_key = " . $this->ilDB->quote($this->key, "text") .
126 " AND module = " . $this->ilDB->quote($module, "text");
127 $set = $this->ilDB->query($q);
128 $row = $this->ilDB->fetchAssoc($set);
129 $arr2 = isset($row["lang_array"]) ? unserialize($row["lang_array"], ["allowed_classes" => false]) : "";
130 if (is_array($arr2)) {
131 $lang_arr = array_merge($arr2, $lang_arr);
132 }
133 }
134 $query .= sprintf(
135 "(%s,%s,%s),",
136 $this->ilDB->quote($module, "text"),
137 $this->ilDB->quote($this->key, "text"),
138 $this->ilDB->quote(serialize($lang_arr), "clob")
139 );
140 $modules_to_delete[] = $module;
141 }
142
143 $inModulesToDelete = $this->ilDB->in('module', $modules_to_delete, false, 'text');
144 $this->ilDB->manipulate(sprintf("DELETE FROM lng_modules WHERE lang_key = %s AND $inModulesToDelete",
145 $this->ilDB->quote($this->key, "text")
146 ));
147
148 $query = rtrim($query, ",") . ";";
149 $this->ilDB->manipulate($query);
150
151 // check if the module is correctly saved
152 // see mantis #20046 and #19140
153 $this->checkModules();
154 }
155
156 protected function checkModules(): void
157 {
158 $result = $this->ilDB->queryF(
159 "SELECT module, lang_array FROM lng_modules WHERE lang_key = %s",
160 array("text"),
161 array($this->key)
162 );
163
164 foreach ($this->ilDB->fetchAll($result) as $module) {
165 $unserialied = unserialize($module["lang_array"], ["allowed_classes" => false]);
166 if (!is_array($unserialied)) {
167 global $DIC;
169 $ilErr = $DIC["ilErr"];
170 $ilErr->raiseError(
171 "Data for module '" . $module["module"] . "' of language '" . $this->key . "' is not correctly saved. " .
172 "Please check the collation of your database tables lng_data and lng_modules. It must be utf8_unicode_ci.",
173 $ilErr->MESSAGE
174 );
175 }
176 }
177 }
178}
$result
An exception for terminatinating execution or to throw for unit testing.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(ilDBInterface $ilDB, string $key, array $content, array $local_changes, string $scope="", string $separator="#:#", string $comment_separator="###")
global $DIC
Definition: goto.php:24
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$query
$ilErr
Definition: raiseError.php:18