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