ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilDBUpdate.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
13{
14
34 public $updateMsg;
38 protected $client_ini;
39
43
44
51 public function __construct($a_db_handler = 0, $client_ini = null)
52 {
53 // workaround to allow setup migration
54 $this->client_ini = $client_ini;
55 if ($a_db_handler) {
56 $this->db = &$a_db_handler;
57 $this->PATH = "./";
58 } else {
59 global $DIC;
60 if ($DIC->offsetExists('mySetup')) {
61 $mySetup = $DIC['mySetup'];
62 }
63 $this->db = $mySetup->db;
64 $this->PATH = "./";
65 }
66
67 $this->getCurrentVersion();
68
69 // get update file for current version
70 $updatefile = $this->getFileForStep($this->currentVersion + 1);
71
72 $this->current_file = $updatefile;
73 $this->DB_UPDATE_FILE = $this->PATH . "setup/sql/" . $updatefile;
74
75 //
76 // NOTE: IF YOU SET THIS TO THE NEWEST FILE, CHANGE ALSO getFileForStep()
77 //
78 $this->LAST_UPDATE_FILE = $this->PATH . "setup/sql/dbupdate_05.php";
79
80 $this->readDBUpdateFile();
81 $this->readLastUpdateFile();
82 $this->readFileVersion();
83 }
84
85
93 public function getFileForStep($a_version)
94 {
95 //
96 // NOTE: IF YOU ADD A NEW FILE HERE, CHANGE ALSO THE CONSTRUCTOR
97 //
98 switch (true) {
99 case ((int) $a_version > 5431): // last number in previous file
100 return "dbupdate_05.php";
101 case ((int) $a_version > 4182): // last number in previous file
102 return "dbupdate_04.php";
103 case ((int) $a_version > 2948): // last number in previous file
104 return "dbupdate_03.php";
105 case ((int) $a_version > 864): // last number in previous file
106 return "dbupdate_02.php";
107 default:
108 return "dbupdate.php";
109 }
110 }
111
112
116 public function initStep($i)
117 {
118 //
119 }
120
121
122 public function readDBUpdateFile()
123 {
124 if (!file_exists($this->DB_UPDATE_FILE)) {
125 $this->error = "no_db_update_file";
126 $this->filecontent = array();
127
128 return false;
129 }
130
131 $this->filecontent = @file($this->DB_UPDATE_FILE);
132
133 return true;
134 }
135
136
137 public function readLastUpdateFile()
138 {
139 if (!file_exists($this->LAST_UPDATE_FILE)) {
140 $this->error = "no_last_update_file";
141 $this->lastfilecontent = array();
142
143 return false;
144 }
145
146 $this->lastfilecontent = @file($this->LAST_UPDATE_FILE);
147
148 return true;
149 }
150
151
155 public function getCurrentVersion()
156 {
157 $set = new ilSetting("common", true);
158 $this->currentVersion = (integer) $set->get("db_version");
159
161 }
162
163
169 public function setCurrentVersion($a_version)
170 {
171 $set = new ilSetting("common", true);
172 $set->set("db_version", $a_version);
173 $this->currentVersion = $a_version;
174
175 return true;
176 }
177
178
184 public function setRunningStatus($a_nr)
185 {
186 $set = new ilSetting("common", true);
187 $set->set("db_update_running", $a_nr);
188 $this->db_update_running = $a_nr;
189 }
190
191
197 public function getRunningStatus()
198 {
199 $set = new ilSetting("common", true);
200 $this->db_update_running = (integer) $set->get("db_update_running");
201
202 return $this->db_update_running;
203 }
204
205
209 public function clearRunningStatus()
210 {
211 $set = new ilSetting("common", true);
212 $set->set("db_update_running", 0);
213 $this->db_update_running = 0;
214 }
215
216
217 public function readFileVersion()
218 {
219 //go through filecontent and search for last occurence of <#x>
220 reset($this->lastfilecontent);
221 $regs = array();
222 $version = 0;
223 foreach ($this->lastfilecontent as $row) {
224 if (preg_match('/^<\#([0-9]+)>/', $row, $regs)) {
225 $version = $regs[1];
226 }
227 }
228
229 $this->fileVersion = (integer) $version;
230
231 return $this->fileVersion;
232 }
233
234
238 public function getFileVersion()
239 {
240 return $this->fileVersion;
241 }
242
243
252 public function execQuery($db, $str)
253 {
254 $sql = explode("\n", trim($str));
255 for ($i = 0; $i < count($sql); $i++) {
256 $sql[$i] = trim($sql[$i]);
257 if ($sql[$i] != "" && substr($sql[$i], 0, 1) != "#") {
258 //take line per line, until last char is ";"
259 if (substr($sql[$i], -1) == ";") {
260 //query is complete
261 $q .= " " . substr($sql[$i], 0, -1);
262 $check = $this->checkQuery($q);
263 if ($check === true) {
264 try {
265 $r = $db->query($q);
266 } catch (ilDatabaseException $e) {
267 var_dump($e); // FSX
268 exit;
269 $this->error = $e->getMessage();
270
271 return false;
272 }
273 } else {
274 $this->error = $check;
275
276 return false;
277 }
278 unset($q);
279 } //if
280 else {
281 $q .= " " . $sql[$i];
282 } //else
283 } //if
284 } //for
285 if (isset($q) && $q != "") {
286 echo "incomplete_statement: " . $q . "<br>";
287
288 return false;
289 }
290
291 return true;
292 }
293
294
298 public function checkQuery($q)
299 {
300 return true;
301 }
302
303
309 private function initGlobalsRequiredForUpdateSteps(&$ilCtrlStructureReader, &$ilMySQLAbstraction, &$ilDB)
310 {
311 global $DIC;
312
313 // TODO: There is currently a huge mixup of globals, $DIC and dependencies, esprecially in setup and during DB-Updates. This leads to many problems. The following core tries to provide the needed dependencies for the dbupdate-script. The code hopefully will change in the future.
314
315 if (isset($GLOBALS['ilCtrlStructureReader'])) {
316 $ilCtrlStructureReader = $GLOBALS['ilCtrlStructureReader'];
317 } elseif ($DIC->offsetExists('ilCtrlStructureReader')) {
318 $ilCtrlStructureReader = $DIC['ilCtrlStructureReader'];
319 } else {
320 $ilCtrlStructureReader = new ilCtrlStructureReader();
321 $DIC->offsetSet('ilCtrlStructureReader', $ilCtrlStructureReader);
322 }
323
324 $GLOBALS['ilCtrlStructureReader'] = $ilCtrlStructureReader;
325
326 if ($DIC->offsetExists('ilMySQLAbstraction')) {
327 $ilMySQLAbstraction = $DIC['ilMySQLAbstraction'];
328 } else {
329 $ilMySQLAbstraction = new ilMySQLAbstraction();
330 $DIC->offsetSet('ilMySQLAbstraction', $ilMySQLAbstraction);
331 }
332
333 $GLOBALS['ilMySQLAbstraction'] = $ilMySQLAbstraction;
334 if ($this->client_ini) {
335 $ilCtrlStructureReader->setIniFile($this->client_ini);
336 }
337 $ilDB = $DIC->database();
338 }
339
340
344 public function applyUpdate($a_break = 0)
345 {
346 $ilCtrlStructureReader = null;
347 $ilMySQLAbstraction = null;
348 $ilDB = null;
349 $this->initGlobalsRequiredForUpdateSteps($ilCtrlStructureReader, $ilMySQLAbstraction, $ilDB);
350
353
354 if ($a_break > $this->currentVersion
355 && $a_break < $this->fileVersion
356 ) {
357 $f = $a_break;
358 }
359
360 if ($c < $f) {
361 $msg = array();
362 for ($i = ($c + 1); $i <= $f; $i++) {
363 // check wether next update file must be loaded
364 if ($this->current_file != $this->getFileForStep($i)) {
365 $this->DB_UPDATE_FILE = $this->PATH . "setup/sql/" . $this->getFileForStep($i);
366 $this->readDBUpdateFile();
367 }
368
369 $this->initStep($i);
370
371 if ($this->applyUpdateNr($i) == false) {
372 $msg[] = array("msg" => "update_error: " . $this->error,
373 "nr" => $i,);
374 $this->updateMsg = $msg;
375
376 return false;
377 } else {
378 $msg[] = array("msg" => "update_applied",
379 "nr" => $i,);
380 }
381 }
382
383 $this->updateMsg = $msg;
384 } else {
385 $this->updateMsg = "no_changes";
386 }
387
388 if ($f < $this->fileVersion) {
389 return true;
390 } else {
391 return $this->loadXMLInfo();
392 }
393 }
394
395
396 public function loadXMLInfo()
397 {
398 $ilCtrlStructureReader = null;
399 $ilMySQLAbstraction = null;
400 $ilDB = null;
401 $this->initGlobalsRequiredForUpdateSteps($ilCtrlStructureReader, $ilMySQLAbstraction, $ilDB);
402
403 // read module and service information into db
406
407 $ilCtrlStructureReader->readStructure();
408
409 $mr = new ilModuleReader("", "", "");
410 $mr->clearTables();
411 foreach ($modules as $module) {
412 $mr = new ilModuleReader(
413 ILIAS_ABSOLUTE_PATH . "/Modules/" . $module["subdir"] . "/module.xml",
414 $module["subdir"],
415 "Modules"
416 );
417 $mr->getModules();
418 unset($mr);
419 }
420
421 $sr = new ilServiceReader("", "", "");
422 $sr->clearTables();
423 foreach ($services as $service) {
424 $sr = new ilServiceReader(
425 ILIAS_ABSOLUTE_PATH . "/Services/" . $service["subdir"] . "/service.xml",
426 $service["subdir"],
427 "Services"
428 );
429 $sr->getServices();
430 unset($sr);
431 }
432
433
434
435 return true;
436 }
437
438
447 public function applyUpdateNr(&$nr, $hotfix = false, $custom_update = false)
448 {
449 $ilCtrlStructureReader = null;
450 $ilMySQLAbstraction = null;
451 $ilDB = null;
452 $this->initGlobalsRequiredForUpdateSteps($ilCtrlStructureReader, $ilMySQLAbstraction, $ilDB);
453
454 //search for desired $nr
455 reset($this->filecontent);
456
457 if (!$hotfix && !$custom_update) {
458 $this->setRunningStatus($nr);
459 }
460
461 //init
462 $i = 0;
463
464 //go through filecontent
465 while (!preg_match("/^<\#" . $nr . ">/", $this->filecontent[$i]) && $i < count($this->filecontent)) {
466 $i++;
467 }
468
469 //update not found
470 if ($i == count($this->filecontent)) {
471 $this->error = "update_not_found";
472
473 return false;
474 }
475
476 $i++;
477
478 //update found, now extract this update to a new array
479 $update = array();
480 while ($i < count($this->filecontent) && !preg_match("/^<#" . ($nr + 1) . ">/", $this->filecontent[$i])) {
481 $update[] = trim($this->filecontent[$i]);
482 $i++;
483 }
484
485 //now you have the update, now process it
486 $sql = array();
487 $php = array();
488 $mode = "sql";
489
490 foreach ($update as $row) {
491 if (preg_match("/<\?php/", $row)) {
492 if (count($sql) > 0) {
493 if ($this->execQuery($this->db, implode("\n", $sql)) == false) {
494 $this->error = $this->error;
495
496 return false;
497 }
498 $sql = array();
499 }
500 $mode = "php";
501 } elseif (preg_match("/\?>/", $row)) {
502 if (count($php) > 0) {
503 $code = implode("\n", $php);
504 if (eval($code) === false) {
505 $this->error = "Parse error: " . $code;
506
507 return false;
508 }
509 $php = array();
510 }
511 $mode = "sql";
512 } else {
513 if ($mode == "sql") {
514 $sql[] = $row;
515 }
516
517 if ($mode == "php") {
518 $php[] = $row;
519 }
520 } //else
521 } //foreach
522
523 if ($mode == "sql" && count($sql) > 0) {
524 if ($this->execQuery($this->db, implode("\n", $sql)) == false) {
525 $this->error = "dump_error: " . $this->error;
526
527 return false;
528 }
529 }
530
531 //increase db_Version number
532 if (!$hotfix && !$custom_update) {
533 $this->setCurrentVersion($nr);
534 } elseif ($hotfix) {
535 $this->setHotfixCurrentVersion($nr);
536 } elseif ($custom_update) {
538 }
539
540 if (!$hotfix && !$custom_update) {
541 $this->clearRunningStatus();
542 }
543
544 //$this->currentVersion = $ilias->getSetting("db_version");
545
546 return true;
547 }
548
549
550 public function getDBVersionStatus()
551 {
552 if ($this->fileVersion > $this->currentVersion) {
553 return false;
554 } else {
555 return true;
556 }
557 }
558
559
560 public function getTables()
561 {
562 $a = array();
563
564 $query = "SHOW TABLES";
565 $res = $this->db->query($query);
566 while ($row = $res->fetchRow()) {
567 $status = $this->getTableStatus($row[0]);
568 $a[] = array("name" => $status["Table"],
569 "table" => $row[0],
570 "status" => $status["Msg_text"],);
571 }
572
573 return $a;
574 }
575
576
577 public function getTableStatus($table)
578 {
579 $a = array();
580
581 $query = "ANALYZE TABLE " . $table;
582 $res = $this->db->query($query);
583 $row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC);
584
585 return $row;
586 }
587
588
592
596 public function getHotfixCurrentVersion()
597 {
598 $this->readHotfixInfo();
599
600 return $this->hotfix_current_version ?? null;
601 }
602
603
607 public function setHotfixCurrentVersion($a_version)
608 {
609 $this->readHotfixInfo();
610 $this->hotfix_setting->set(
611 "db_hotfixes_" . $this->hotfix_version[0],
612 $a_version
613 );
614 $this->hotfix_current_version = $a_version;
615
616 return true;
617 }
618
619
623 public function getHotfixFileVersion()
624 {
625 $this->readHotfixInfo();
626
627 return $this->hotfix_file_version ?? null;
628 }
629
630
634 public function readHotfixFileVersion($a_file_content)
635 {
636 //go through filecontent and search for last occurence of <#x>
637 reset($a_file_content);
638 $regs = array();
639 foreach ($a_file_content as $row) {
640 if (preg_match("/^<#([0-9]+)>/", $row, $regs)) {
641 $version = $regs[1];
642 }
643 }
644
645 return (integer) $version;
646 }
647
648
652 public function readHotfixInfo($a_force = false)
653 {
654 if (isset($this->hotfix_info_read) && $this->hotfix_info_read && !$a_force) {
655 return;
656 }
657 $this->hotfix_setting = new ilSetting("common", true);
658 $ilias_version = ILIAS_VERSION_NUMERIC;
659 $version_array = explode(".", $ilias_version);
660 $this->hotfix_version[0] = $version_array[0];
661 $this->hotfix_version[1] = $version_array[1];
662 $hotfix_file = $this->PATH . "setup/sql/" . $this->hotfix_version[0] . "_hotfixes.php";
663 if (is_file($hotfix_file)) {
664 $this->hotfix_content = @file($hotfix_file);
665 $this->hotfix_current_version = (int) $this->hotfix_setting->get(
666 "db_hotfixes_" . $this->hotfix_version[0]
667 );
668 $this->hotfix_file_version = $this->readHotfixFileVersion($this->hotfix_content);
669 }
670 $this->hotfix_info_read = true;
671 }
672
673
677 public function hotfixAvailable()
678 {
679 $this->readHotfixInfo();
680 if (isset($this->hotfix_file_version) && $this->hotfix_file_version > $this->hotfix_current_version) {
681 return true;
682 }
683
684 return false;
685 }
686
687
691 public function applyHotfix()
692 {
693 $ilCtrlStructureReader = null;
694 $ilMySQLAbstraction = null;
695 $ilDB = null;
696 $this->initGlobalsRequiredForUpdateSteps($ilCtrlStructureReader, $ilMySQLAbstraction, $ilDB);
697
698 $ilMySQLAbstraction = new ilMySQLAbstraction();
699 $GLOBALS['DIC']['ilMySQLAbstraction'] = $ilMySQLAbstraction;
700
701 $this->readHotfixInfo(true);
702
703 $f = $this->getHotfixFileVersion();
704 $c = $this->getHotfixCurrentVersion();
705
706 if ($c < $f) {
707 $msg = array();
708 for ($i = ($c + 1); $i <= $f; $i++) {
709 // $this->initStep($i); // nothings happens here
710
711 $this->filecontent = $this->hotfix_content;
712
713 if ($this->applyUpdateNr($i, true) == false) {
714 $msg[] = array("msg" => "update_error: " . $this->error,
715 "nr" => $i,);
716 $this->updateMsg = $msg;
717
718 return false;
719 } else {
720 $msg[] = array("msg" => "hotfix_applied",
721 "nr" => $i,);
722 }
723 }
724
725 $this->updateMsg = $msg;
726 } else {
727 $this->updateMsg = "no_changes";
728 }
729
730 return $this->loadXMLInfo();
731 }
732
733
735 {
736 $this->readCustomUpdatesInfo();
737
739 }
740
741
742 public function setCustomUpdatesCurrentVersion($a_version)
743 {
744 $this->readCustomUpdatesInfo();
745 $this->custom_updates_setting->set('db_version_custom', $a_version);
746 $this->custom_updates_current_version = $a_version;
747
748 return true;
749 }
750
751
753 {
754 $this->readCustomUpdatesInfo();
755
757 }
758
759
760 public function readCustomUpdatesFileVersion($a_file_content)
761 {
762 //go through filecontent and search for last occurence of <#x>
763 reset($a_file_content);
764 $regs = array();
765 foreach ($a_file_content as $row) {
766 if (preg_match("/^<#([0-9]+)>/", $row, $regs)) {
767 $version = $regs[1];
768 }
769 }
770
771 return (integer) $version;
772 }
773
774
775 public function readCustomUpdatesInfo($a_force = false)
776 {
777 if ($this->custom_updates_info_read && !$a_force) {
778 return;
779 }
780
781 $this->custom_updates_setting = new ilSetting();
782 $custom_updates_file = $this->PATH . "setup/sql/dbupdate_custom.php";
783 if (is_file($custom_updates_file)) {
784 $this->custom_updates_content = @file($custom_updates_file);
785 $this->custom_updates_current_version = (int) $this->custom_updates_setting->get('db_version_custom', 0);
786 $this->custom_updates_file_version = $this->readCustomUpdatesFileVersion($this->custom_updates_content);
787 }
788 $this->custom_updates_info_read = true;
789 }
790
791
792 public function customUpdatesAvailable()
793 {
794 // trunk does not support custom updates
795 // return false;
796
797 $this->readCustomUpdatesInfo();
798 if ($this->custom_updates_file_version > $this->custom_updates_current_version) {
799 return true;
800 }
801
802 return false;
803 }
804
805
806 public function applyCustomUpdates()
807 {
808 $ilCtrlStructureReader = null;
809 $ilMySQLAbstraction = null;
810 $ilDB = null;
811 $this->initGlobalsRequiredForUpdateSteps($ilCtrlStructureReader, $ilMySQLAbstraction, $ilDB);
812
813 $ilMySQLAbstraction = new ilMySQLAbstraction();
814 $GLOBALS['DIC']['ilMySQLAbstraction'] = $ilMySQLAbstraction;
815
816 $this->readCustomUpdatesInfo(true);
817
820
821 if ($c < $f) {
822 $msg = array();
823 for ($i = ($c + 1); $i <= $f; $i++) {
824 $this->filecontent = $this->custom_updates_content;
825
826 if ($this->applyUpdateNr($i, false, true) == false) {
827 $msg[] = array("msg" => "update_error: " . $this->error,
828 "nr" => $i,);
829 $this->updateMsg = $msg;
830
831 return false;
832 } else {
833 $msg[] = array("msg" => "custom_update_applied",
834 "nr" => $i,);
835 }
836 }
837
838 $this->updateMsg = $msg;
839 } else {
840 $this->updateMsg = "no_changes";
841 }
842
843 return $this->loadXMLInfo();
844 }
845
846
852 public function getUpdateSteps($a_break = 0)
853 {
854 $ilCtrlStructureReader = null;
855 $ilMySQLAbstraction = null;
856 $ilDB = null;
857 $this->initGlobalsRequiredForUpdateSteps($ilCtrlStructureReader, $ilMySQLAbstraction, $ilDB);
858
859 $str = "";
860
863
864 if ($a_break > $this->currentVersion
865 && $a_break < $this->fileVersion
866 ) {
867 $f = $a_break;
868 }
869
870 if ($c < $f) {
871 $msg = array();
872 for ($i = ($c + 1); $i <= $f; $i++) {
873 // check wether next update file must be loaded
874 if ($this->current_file != $this->getFileForStep($i)) {
875 $this->DB_UPDATE_FILE = $this->PATH . "setup/sql/" . $this->getFileForStep($i);
876 $this->readDBUpdateFile();
877 }
878
879 $str .= $this->getUpdateStepNr($i);
880 }
881 }
882
883 return $str;
884 }
885
886
892 public function getHotfixSteps()
893 {
894 $this->readHotfixInfo(true);
895
896 $str = "";
897
898 $f = $this->getHotfixFileVersion();
899 $c = $this->getHotfixCurrentVersion();
900
901 if ($c < $f) {
902 $msg = array();
903 for ($i = ($c + 1); $i <= $f; $i++) {
904 $this->filecontent = $this->hotfix_content;
905
906 $str .= $this->getUpdateStepNr($i, true);
907 }
908 }
909
910 return $str;
911 }
912
913
917 public function getUpdateStepNr($nr, $hotfix = false, $custom_update = false)
918 {
919 $str = "";
920
921 //search for desired $nr
922 reset($this->filecontent);
923
924 //init
925 $i = 0;
926
927 //go through filecontent
928 while (!preg_match("/^<#" . $nr . ">/", $this->filecontent[$i]) && $i < count($this->filecontent)) {
929 $i++;
930 }
931
932 //update not found
933 if ($i == count($this->filecontent)) {
934 return false;
935 }
936
937 $i++;
938
939 //update found, now extract this update to a new array
940 $update = array();
941 while ($i < count($this->filecontent) && !preg_match("/^<#" . ($nr + 1) . ">/", $this->filecontent[$i])) {
942 $str .= $this->filecontent[$i];
943 $i++;
944 }
945
946 return "<pre><b><#" . $nr . "></b>\n" . htmlentities($str) . "</pre>";
947 }
948}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
An exception for terminatinating execution or to throw for unit testing.
error($a_errmsg)
set error message @access public
Class ilCtrlStructureReader.
Database Update class.
getUpdateStepNr($nr, $hotfix=false, $custom_update=false)
Get single update step for presentation.
getFileVersion()
Get Version of file.
applyUpdate($a_break=0)
Apply update.
readCustomUpdatesInfo($a_force=false)
__construct($a_db_handler=0, $client_ini=null)
ilDBUpdate constructor.
$DB_UPDATE_FILE
db update file
getHotfixSteps()
Get hotfix steps.
setCurrentVersion($a_version)
getFileForStep($a_version)
Get db update file name for db step.
getUpdateSteps($a_break=0)
Get update steps as string (for presentation)
setRunningStatus($a_nr)
Set running status for a step.
getCustomUpdatesCurrentVersion()
setHotfixCurrentVersion($a_version)
Set current hotfix version.
initGlobalsRequiredForUpdateSteps(&$ilCtrlStructureReader, &$ilMySQLAbstraction, &$ilDB)
execQuery($db, $str)
execute a query
checkQuery($q)
check query
getHotfixCurrentVersion()
Get current hotfix version.
getHotfixFileVersion()
Get current hotfix version.
readHotfixInfo($a_force=false)
Get status of hotfix file.
readCustomUpdatesFileVersion($a_file_content)
hotfixAvailable()
Get status of hotfix file.
setCustomUpdatesCurrentVersion($a_version)
applyUpdateNr(&$nr, $hotfix=false, $custom_update=false)
apply an update
getTableStatus($table)
clearRunningStatus()
Clear running status.
applyHotfix()
Apply hotfix.
getRunningStatus()
Get running status.
readHotfixFileVersion($a_file_content)
Set current hotfix version.
Class ilDatabaseException.
Class ilModuleReader.
static getAvailableCoreModules()
Get all available core modules.
This class includes methods that help to abstract ILIAS 3.10.x MySQL tables for the use with MDB2 abs...
Class ilServiceReader.
static getAvailableCoreServices()
Get all available core services.
ILIAS Setting Class.
$c
Definition: cli.php:37
global $DIC
Definition: goto.php:24
const ILIAS_VERSION_NUMERIC
exit
Definition: login.php:29
$i
Definition: metadata.php:24
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
const PATH
Definition: proxy_ylocal.php:8
$query
$service
Definition: result.php:17
foreach($_POST as $key=> $value) $res
global $ilDB