ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilCtrlStructureReader.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
14{
17 public $executed;
18 public $db = null;
19
20 public function __construct($a_ini_file = null)
21 {
22 $this->class_script = array();
23 $this->class_childs = array();
24 $this->executed = false;
25 $this->ini = $a_ini_file;
26 }
27
28 public function setIniFile($a_ini_file)
29 {
30 $this->ini = $a_ini_file;
31 }
32
36 public function getStructure()
37 {
38 $ilDB = $this->getDB();
39
40 $this->ini->setVariable("db", "structure_reload", "1");
41 $this->ini->write();
42 if ($this->ini->readVariable("db", "structure_reload") != "1") {
43 echo "Error Cannot write client.ini.file.";
44 }
45 //$this->get_structure = true;
46 }
47
51 public function readStructure(
52 $a_force = false,
53 $a_dir = "",
54 $a_comp_prefix = "",
55 $a_plugin_path = ""
56 ) {
57 $ilDB = $this->getDB();
58
59 if (!$a_force && $this->ini->readVariable("db", "structure_reload") != "1") {
60 return;
61 }
62
63 require_once('./Services/UICore/classes/class.ilCachedCtrl.php');
65 require_once('./Services/GlobalCache/classes/class.ilGlobalCache.php');
66 ilGlobalCache::flushAll();
67
68 // prefix for component
69 $this->comp_prefix = $a_comp_prefix;
70
71 // plugin path
72 $this->plugin_path = $a_plugin_path;
73
74 // only run one time per db_update request
75 if (!$this->executed) {
76 if ($a_dir == "") {
77 $this->start_dir = ILIAS_ABSOLUTE_PATH;
78 $this->read(ILIAS_ABSOLUTE_PATH);
79 } else {
80 $this->start_dir = $a_dir;
81 $this->read($a_dir);
82 }
83 $this->store();
84 $this->determineClassFileIds();
85 $this->executed = true;
86 if (!$a_force) {
87 $this->ini->setVariable("db", "structure_reload", "0");
88 $this->ini->write();
89 }
90 }
91 }
92
97 private function normalizePath(string $path) : string
98 {
99 return realpath(str_replace(['//'], ['/'], $path));
100 }
101
107 public function read($a_cdir)
108 {
109 $ilDB = $this->getDB();
110 if (defined(ILIAS_ABSOLUTE_PATH)) {
111 $il_absolute_path = ILIAS_ABSOLUTE_PATH;
112 } else {
113 $il_absolute_path = dirname(__FILE__, 5);
114 }
115
116 // check wether $a_cdir is a directory
117 if (!@is_dir($a_cdir)) {
118 return false;
119 }
120
121 // read current directory
122 $dir = opendir($a_cdir);
123
124 while ($file = readdir($dir)) {
125 if ($file != "." and
126 $file != "..") {
127 // directories
128 if (@is_dir($a_cdir . "/" . $file)) {
129 if ($this->normalizePath($a_cdir . "/" . $file) != $this->normalizePath($il_absolute_path . "/data") &&
130 $this->normalizePath($a_cdir . "/" . $file) != $this->normalizePath($il_absolute_path . "/Customizing")
131 ) {
132 $this->read($a_cdir . "/" . $file);
133 }
134 }
135
136 // files
137 if (@is_file($a_cdir . "/" . $file)) {
138 if (preg_match("~^class.*php$~i", $file) || preg_match("~^ilSCORM13Player.php$~i", $file)) {
139 $handle = fopen($a_cdir . "/" . $file, "r");
140 //echo "<br>".$a_cdir."/".$file;
141 while (!feof($handle)) {
142 $line = fgets($handle, 4096);
143
144 // handle @ilctrl_calls
145 $pos = strpos(strtolower($line), "@ilctrl_calls");
146 if (is_int($pos)) {
147 $com = substr($line, $pos + 14);
148 $pos2 = strpos($com, ":");
149 if (is_int($pos2)) {
150 $com_arr = explode(":", $com);
151 $parent = strtolower(trim($com_arr[0]));
152
153 // check file duplicates
154 if ($parent != "" && isset($this->class_script[$parent]) &&
155 $this->class_script[$parent] != $a_cdir . "/" . $file) {
156 // delete all class to file assignments
157 $ilDB->manipulate("DELETE FROM ctrl_classfile WHERE comp_prefix = " .
158 $ilDB->quote($this->comp_prefix, "text"));
159 if ($this->comp_prefix == "") {
160 $ilDB->manipulate($q = "DELETE FROM ctrl_classfile WHERE " .
161 $ilDB->equals("comp_prefix", "", "text", true));
162 }
163
164 // delete all call entries
165 $ilDB->manipulate("DELETE FROM ctrl_calls WHERE comp_prefix = " .
166 $ilDB->quote($this->comp_prefix, "text"));
167 if ($this->comp_prefix == "") {
168 $ilDB->manipulate("DELETE FROM ctrl_calls WHERE comp_prefix IS NULL");
169 }
170
171 $msg = implode("\n", [
172 "Error: Duplicate call structure definition found (Class %s) in files:",
173 "- %s",
174 "- %s",
175 "",
176 "Please remove the file, that does not belong to the official ILIAS distribution.",
177 "After that invoke 'Tools' -> 'Reload Control Structure' in the ILIAS Setup."
178 ]);
179
180 throw new \Exception(
181 sprintf(
182 $msg,
183 $parent,
184 $this->class_script[$parent],
185 $a_cdir . "/" . $file
186 )
187 );
188 }
189
190 $this->class_script[$parent] = $a_cdir . "/" . $file;
191 $childs = explode(",", $com_arr[1]);
192 foreach ($childs as $child) {
193 $child = trim(strtolower($child));
194 if (!isset($this->class_childs[$parent]) || !is_array($this->class_childs[$parent]) || !in_array($child, $this->class_childs[$parent])) {
195 $this->class_childs[$parent][] = $child;
196 }
197 }
198 }
199 }
200
201 // handle isCalledBy comments
202 $pos = strpos(strtolower($line), "@ilctrl_iscalledby");
203 if (is_int($pos)) {
204 $com = substr($line, $pos + 19);
205 $pos2 = strpos($com, ":");
206 if (is_int($pos2)) {
207 $com_arr = explode(":", $com);
208 $child = strtolower(trim($com_arr[0]));
209 $this->class_script[$child] = $a_cdir . "/" . $file;
210
211 $parents = explode(",", $com_arr[1]);
212 foreach ($parents as $parent) {
213 $parent = trim(strtolower($parent));
214 if (!isset($this->class_childs[$parent]) || !is_array($this->class_childs[$parent]) || !in_array($child, $this->class_childs[$parent])) {
215 $this->class_childs[$parent][] = $child;
216 }
217 }
218 }
219 }
220
221 if (preg_match("~^class\.(.*GUI)\.php$~i", $file, $res)) {
222 $cl = strtolower($res[1]);
223 $pos = strpos(strtolower($line), "class " . $cl);
224 if (is_int($pos) && (!isset($this->class_script[$cl]) || $this->class_script[$cl] == "")) {
225 $this->class_script[$cl] = $a_cdir . "/" . $file;
226 //echo "<br>".$cl."-".$this->class_script[$cl]."-";
227 }
228 }
229 }
230 fclose($handle);
231 }
232 }
233 }
234 }
235 }
236
242 public function store($a_cdir = "./..")
243 {
244 $ilDB = $this->getDB();
245
246 // delete all class to file assignments
247 $ilDB->manipulate("DELETE FROM ctrl_classfile WHERE comp_prefix = " .
248 $ilDB->quote($this->comp_prefix, "text"));
249 if ($this->comp_prefix == "") {
250 $ilDB->manipulate($q = "DELETE FROM ctrl_classfile WHERE " .
251 $ilDB->equals("comp_prefix", "", "text", true));
252 }
253
254 // delete all call entries
255 $ilDB->manipulate("DELETE FROM ctrl_calls WHERE comp_prefix = " .
256 $ilDB->quote($this->comp_prefix, "text"));
257 if ($this->comp_prefix == "") {
258 $ilDB->manipulate("DELETE FROM ctrl_calls WHERE " .
259 $ilDB->equals("comp_prefix", "", "text", true));
260 }
261
262 foreach ($this->class_script as $class => $script) {
263 $file = substr($script, strlen($this->start_dir) + 1);
264
265 // store class to file assignment
266 $ilDB->manipulate(sprintf(
267 "INSERT INTO ctrl_classfile (class, filename, comp_prefix, plugin_path) " .
268 " VALUES (%s,%s,%s,%s)",
269 $ilDB->quote($class, "text"),
270 $ilDB->quote($file, "text"),
271 $ilDB->quote($this->comp_prefix, "text"),
272 $ilDB->quote($this->plugin_path, "text")
273 ));
274 }
275 //$this->class_childs[$parent][] = $child;
276 foreach ($this->class_childs as $parent => $v) {
277 if (is_array($this->class_childs[$parent])) {
278 foreach ($this->class_childs[$parent] as $child) {
279 if (strlen(trim($child)) and strlen(trim($parent))) {
280 // store call entry
281 $ilDB->manipulate(sprintf(
282 "INSERT INTO ctrl_calls (parent, child, comp_prefix) " .
283 "VALUES (%s,%s,%s)",
284 $ilDB->quote($parent, "text"),
285 $ilDB->quote($child, "text"),
286 $ilDB->quote($this->comp_prefix, "text")
287 ));
288 }
289 }
290 }
291 }
292 }
293
297 public function determineClassFileIds()
298 {
299 $ilDB = $this->getDB();
300
301 $ilDB->manipulate(
302 "UPDATE ctrl_classfile SET " .
303 " cid = " . $ilDB->quote("", "text")
304 );
305 $set = $ilDB->query("SELECT * FROM ctrl_classfile ");
306 $cnt = 1;
307 while ($rec = $ilDB->fetchAssoc($set)) {
308 $cid = base_convert((string) $cnt, 10, 36);
309 $ilDB->manipulate(
310 "UPDATE ctrl_classfile SET " .
311 " cid = " . $ilDB->quote($cid, "text") .
312 " WHERE class = " . $ilDB->quote($rec["class"], "text")
313 );
314 $cnt++;
315 }
316 }
317
318 public function withDB(\ilDBInterface $db)
319 {
320 $clone = clone $this;
321 $clone->db = $db;
322 return $clone;
323 }
324
325 protected function getDB() : \ilDBInterface
326 {
327 if (!is_null($this->db)) {
328 return $this->db;
329 }
330 //return ilDB in any case - backward compat.
331 global $ilDB;
332 return $ilDB;
333 }
334}
An exception for terminatinating execution or to throw for unit testing.
Class ilCtrlStructureReader.
determineClassFileIds()
Determine class file IDS.
store($a_cdir="./..")
read structure into internal variables
readStructure( $a_force=false, $a_dir="", $a_comp_prefix="", $a_plugin_path="")
read structure
read($a_cdir)
read structure into internal variables
getStructure()
parse code files and store call structure in db
Interface ilDBInterface.
foreach($_POST as $key=> $value) $res
global $ilDB