ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilDBGenerator.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
4
13class ilDBGenerator
14{
15
19 protected $target_encoding = 'UTF-8';
23 protected $whitelist = array();
27 protected $blacklist = array();
31 protected $tables = array();
35 protected $filter = array();
36
37
41 public function __construct()
42 {
43 global $DIC;
44 $ilDB = $DIC->database();
45
46 $this->manager = $ilDB->loadModule(ilDBConstants::MODULE_MANAGER);
47 $this->reverse = $ilDB->loadModule(ilDBConstants::MODULE_REVERSE);
48 $this->il_db = $ilDB;
49 include_once("./Services/Database/classes/class.ilDBAnalyzer.php");
50 $this->analyzer = new ilDBAnalyzer();
51
52 $this->allowed_attributes = $ilDB->getAllowedAttributes();
53 }
54
59 public static function lookupAbstractedTables()
60 {
61 global $DIC;
62 $ilDB = $DIC->database();
63
64 $query = "SELECT DISTINCT(table_name) FROM abstraction_progress ";
65 $res = $ilDB->query($query);
66 $names = array();
67 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
68 $names[] = $row->table_name;
69 }
70
71 // tables that have been already created in an abstracted
72 // way or tables that have been renamed after being abstracted
73 // (see db_update script)
74 $abs_tables = array_merge($names, array(
75 'acc_access_key',
76 'acc_user_access_key',
77 'ldap_rg_mapping',
78 'page_anchor',
79 'qpl_question_orderinghorizontal',
80 'qpl_question_fileupload',
81 'chat_smilies',
82 'style_color',
83 'style_template_class',
84 'style_template',
85 'page_style_usage',
86 'style_setting',
87 'page_editor_settings',
88 'mep_data',
89 'license_data',
90 'loginname_history',
91 'mep_item',
92 'qpl_a_cloze',
93 'qpl_a_imagemap',
94 'qpl_a_matching',
95 'qpl_num_range',
96 'qpl_qst_cloze',
97 'qpl_qst_essay',
98 'qpl_qst_fileupload',
99 'qpl_qst_flash',
100 'qpl_qst_horder',
101 'qpl_qst_imagemap',
102 'qpl_qst_javaapplet',
103 'qpl_qst_matching',
104 'qpl_qst_mc',
105 'qpl_qst_numeric',
106 'qpl_qst_ordering',
107 'qpl_qst_sc',
108 'qpl_qst_textsubset',
109 'qpl_qst_type',
110 'qpl_sol_sug',
111 'udf_text',
112 'udf_clob',
113 'xmlnestedsettmp',
114 'cache_text',
115 'cache_clob',
116 'qpl_a_errortext',
117 'qpl_qst_errortext',
118 'tst_rnd_cpy',
119 'tst_rnd_qpl_title',
120 'qpl_a_mdef',
121 ));
122
123 return $abs_tables;
124 }
125
126
147 public function setTargetEncoding($a_encoding)
148 {
149 $this->target_encoding = $a_encoding;
150 }
151
152
158 public function getTargetEncoding()
159 {
160 return $this->target_encoding;
161 }
162
163
170 public function setBlackList($a_blacklist)
171 {
172 $this->blacklist = $a_blacklist;
173 }
174
175
181 public function getBlackList()
182 {
183 return $this->blacklist;
184 }
185
186
194 public function setWhiteList($a_whitelist)
195 {
196 $this->whitelist = $a_whitelist;
197 }
198
199
205 public function getWhiteList()
206 {
207 return $this->whitelist;
208 }
209
210
215 public function setFilter($a_filter, $a_value)
216 {
217 $this->filter[$a_filter] = $a_value;
218 }
219
220
224 public function getTables()
225 {
226 $r = $this->manager->listTables();
227 $this->tables = $r;
228
229 return $this->tables;
230 }
231
232
236 public function checkProcessing($a_table)
237 {
238 // check black list
239 if (in_array($a_table, $this->blacklist)) {
240 return false;
241 }
242
243 // check white list
244 if (count($this->whitelist) > 0 && !in_array($a_table, $this->whitelist)) {
245 return false;
246 }
247
248 return true;
249 }
250
251
252 protected function openFile($a_path)
253 {
254 if (1) {
255 $file = fopen($a_path, "w");
256 $start .= "\t" . 'global $ilDB;' . "\n\n";
257 fwrite($file, $start);
258
259 return $file;
260 }
261
262 $file = fopen($a_path, "w");
263 $start = '<?php' . "\n" . 'function setupILIASDatabase()' . "\n{\n";
264 $start .= "\t" . 'global $ilDB;' . "\n\n";
265 fwrite($file, $start);
266
267 return $file;
268 }
269
270
271 protected function closeFile($fp)
272 {
273 if (1) {
274 #fwrite ($fp, $end);
275 fclose($fp);
276
277 return;
278 }
279
280 $end = "\n}\n?>\n";
281 fwrite($fp, $end);
282 fclose($fp);
283 }
284
285
291 public function buildDBGenerationScript($a_filename = "")
292 {
293 if (@is_dir($a_filename)) {
294 $isDirectory = true;
295 $path = $a_filename;
296 } else {
297 $isDirectory = false;
298 $path = '';
299 }
300
301 $file = "";
302 if ($a_filename != "" and !$isDirectory) {
303 $file = fopen($a_filename, "w");
304
305 $start = '<?php' . "\n" . 'function setupILIASDatabase()' . "\n{\n";
306 $start .= "\t" . 'global $ilDB;' . "\n\n";
307 fwrite($file, $start);
308 } elseif ($isDirectory) {
309 ;
310 } else {
311 echo "<pre>";
312 }
313
314 $this->getTables();
315
316 foreach ($this->tables as $table) {
317 if ($this->checkProcessing($table)) {
318 if ($a_filename != "") {
319 flush();
320 }
321
322 if ($isDirectory) {
323 $file = $this->openFile($path . '/' . $table);
324 }
325
326 // create table statement
327 $this->buildCreateTableStatement($table, $file);
328
329 // primary key
330 $this->buildAddPrimaryKeyStatement($table, $file);
331
332 // indices
333 $this->buildAddIndexStatements($table, $file);
334
335 // constraints (currently unique keys)
336 $this->buildAddUniqueConstraintStatements($table, $file);
337
338 // auto increment sequence
339 $this->buildCreateSequenceStatement($table, $file);
340
341 if (in_array($table, array('usr_session_stats', 'usr_session_raw'))) {
342 continue;
343 }
344
345 // inserts
346 if ($isDirectory) {
347 $this->buildInsertStatement($table, $path);
348 #$this->buildInsertStatementsXML($table,$path);
349 } else {
350 $this->buildInsertStatements($table, $file);
351 }
352
353 if ($isDirectory) {
354 $this->closeFile($file);
355 }
356 } else {
357 if ($a_filename != "") {
358 echo "<br><b>missing: " . $table . "</b>";
359 flush();
360 }
361 }
362 }
363
364 // sequence(s) without table (of same name)
365 $this->buildSingularSequenceStatement($file);
366
367 if ($a_filename == "") {
368 echo "</pre>";
369 } elseif (!$isDirectory) {
370 $end = "\n}\n?>\n";
371 $ok = fwrite($file, $end);
372 var_dump($ok);
373 fclose($file);
374 }
375 }
376
377
384 public function buildCreateTableStatement($a_table, $a_file = "")
385 {
386 $fields = $this->analyzer->getFieldInformation($a_table, true);
387 $this->fields = $fields;
388 $create_st = "\n\n//\n// " . $a_table . "\n//\n";
389 $create_st .= '$fields = array (' . "\n";
390 $f_sep = "";
391 foreach ($fields as $f => $def) {
392 $create_st .= "\t" . $f_sep . '"' . $f . '" => array (' . "\n";
393 $f_sep = ",";
394 $a_sep = "";
395 foreach ($def as $k => $v) {
396 if ($k != "nativetype" && $k != "alt_types" && $k != "autoincrement" && !is_null($v)) {
397 switch ($k) {
398 case "notnull":
399 case "unsigned":
400 case "fixed":
401 $v = $v ? "true" : "false";
402 break;
403
404 case "default":
405 case "type":
406 $v = '"' . $v . '"';
407 break;
408
409 default:
410 break;
411 }
412 $create_st .= "\t\t" . $a_sep . '"' . $k . '" => ' . $v . "\n";
413 $a_sep = ",";
414 }
415 }
416 $create_st .= "\t" . ')' . "\n";
417 }
418 $create_st .= ');' . "\n";
419 $create_st .= '$ilDB->createTable("' . $a_table . '", $fields);' . "\n";
420
421 if ($a_file == "") {
422 echo $create_st;
423 } else {
424 fwrite($a_file, $create_st);
425 }
426 }
427
428
435 public function buildAddPrimaryKeyStatement($a_table, $a_file = "")
436 {
437 $pk = $this->analyzer->getPrimaryKeyInformation($a_table);
438
439 if (is_array($pk["fields"]) && count($pk["fields"]) > 0) {
440 $pk_st = "\n" . '$pk_fields = array(';
441 $sep = "";
442 foreach ($pk["fields"] as $f => $pos) {
443 $pk_st .= $sep . '"' . $f . '"';
444 $sep = ",";
445 }
446 $pk_st .= ");\n";
447 $pk_st .= '$ilDB->addPrimaryKey("' . $a_table . '", $pk_fields);' . "\n";
448
449 if ($a_file == "") {
450 echo $pk_st;
451 } else {
452 fwrite($a_file, $pk_st);
453 }
454 }
455 }
456
457
464 public function buildAddIndexStatements($a_table, $a_file = "")
465 {
466 $ind = $this->analyzer->getIndicesInformation($a_table, true);
467
468 if (is_array($ind)) {
469 foreach ($ind as $i) {
470 if ($i["fulltext"]) {
471 $ft = ", true";
472 } else {
473 $ft = ", false";
474 }
475 $in_st = "\n" . '$in_fields = array(';
476 $sep = "";
477 foreach ($i["fields"] as $f => $pos) {
478 $in_st .= $sep . '"' . $f . '"';
479 $sep = ",";
480 }
481 $in_st .= ");\n";
482 $in_st .= '$ilDB->addIndex("' . $a_table . '", $in_fields, "' . $i["name"] . '"' . $ft . ');' . "\n";
483
484 if ($a_file == "") {
485 echo $in_st;
486 } else {
487 fwrite($a_file, $in_st);
488 }
489 }
490 }
491 }
492
493
500 public function buildAddUniqueConstraintStatements($a_table, $a_file = "")
501 {
502 $con = $this->analyzer->getConstraintsInformation($a_table, true);
503
504 if (is_array($con)) {
505 foreach ($con as $i) {
506 $in_st = "\n" . '$in_fields = array(';
507 $sep = "";
508 foreach ($i["fields"] as $f => $pos) {
509 $in_st .= $sep . '"' . $f . '"';
510 $sep = ",";
511 }
512 $in_st .= ");\n";
513 $in_st .= '$ilDB->addUniqueConstraint("' . $a_table . '", $in_fields, "' . $i["name"] . '");' . "\n";
514
515 if ($a_file == "") {
516 echo $in_st;
517 } else {
518 fwrite($a_file, $in_st);
519 }
520 }
521 }
522 }
523
524
531 public function buildCreateSequenceStatement($a_table, $a_file = "")
532 {
533 $seq = $this->analyzer->hasSequence($a_table);
534 if ($seq !== false) {
535 $seq_st = "\n" . '$ilDB->createSequence("' . $a_table . '", ' . (int) $seq . ');' . "\n";
536
537 if ($a_file == "") {
538 echo $seq_st;
539 } else {
540 fwrite($a_file, $seq_st);
541 }
542 }
543 }
544
545
551 public function buildSingularSequenceStatement($a_file = "")
552 {
553 $r = $this->manager->listSequences();
554
555 foreach ($r as $seq) {
556 if (!in_array($seq, $this->tables)) {
557 // 12570
558 if ($seq == "sahs_sc13_seq") {
559 continue;
560 }
561
562 $create_st = "\n" . '$ilDB->createSequence("' . $seq . '");' . "\n";
563
564 if ($a_file == "") {
565 echo $create_st;
566 } else {
567 fwrite($a_file, $create_st);
568 }
569 }
570 }
571 }
572
573
581 public function buildInsertStatement($a_table, $a_basedir)
582 {
583 global $DIC;
584 $ilLogger = $DIC->logger()->root();
585
586 $ilLogger->log('Starting export of:' . $a_table);
587
588 $set = $this->il_db->query("SELECT * FROM " . $this->il_db->quoteIdentifier($a_table));
589 $row = 0;
590
591 umask(0000);
592 mkdir($a_basedir . '/' . $a_table . '_inserts', fileperms($a_basedir));
593
594 $filenum = 1;
595 while ($rec = $this->il_db->fetchAssoc($set)) {
596 $values = array();
597 foreach ($rec as $f => $v) {
598 if ($this->fields[$f]['type'] == 'text' and $this->fields[$f]['length'] >= 1000) {
599 $v = $this->shortenText($a_table, $f, $v, $this->fields[$f]['length']);
600 }
601
602 $values[$f] = array(
603 $this->fields[$f]['type'],
604 $v,
605 );
606 }
607
608 $rows[$a_table][$row++] = $values;
609
610 if ($row >= 1000) {
611 $ilLogger->log('Writing insert statements after 1000 lines...');
612 $fp = fopen($a_basedir . '/' . $a_table . '_inserts/' . $filenum++ . '.data', 'w');
613 fwrite($fp, serialize((array) $rows));
614 fclose($fp);
615
616 $row = 0;
617 unset($rows);
618 }
619 }
620 if ($rows) {
621 $fp = fopen($a_basedir . '/' . $a_table . '_inserts/' . $filenum++ . '.data', 'w');
622 fwrite($fp, serialize((array) $rows) . "\n");
623 fclose($fp);
624 }
625
626 $ilLogger->log('Finished export of: ' . $a_table);
627 if (function_exists('memory_get_usage')) {
628 $ilLogger->log('Memory usage: ' . memory_get_usage(true));
629 }
630
631 return true;
632 }
633
634
641 public function buildInsertStatementsXML($a_table, $a_basedir)
642 {
643 include_once './Services/Xml/classes/class.ilXmlWriter.php';
644 $w = new ilXmlWriter();
645 $w->xmlStartTag('Table', array( 'name' => $a_table ));
646
647 $set = $this->il_db->query("SELECT * FROM " . $this->il_db->quoteIdentifier($a_table));
648 $ins_st = "";
649 $first = true;
650 while ($rec = $this->il_db->fetchAssoc($set)) {
651 #$ilLog->write('Num: '.$num++);
652 $w->xmlStartTag('Row');
653
654 $fields = array();
655 $types = array();
656 $values = array();
657 foreach ($rec as $f => $v) {
658 if ($this->fields[$f]['type'] == 'text' and $this->fields[$f]['length'] >= 1000) {
659 $v = $this->shortenText($a_table, $f, $v, $this->fields[$f]['length']);
660 }
661
662 $w->xmlElement('Value', array(
663 'name' => $f,
664 'type' => $this->fields[$f]['type'],
665 ), $v);
666 }
667
668 $w->xmlEndTag('Row');
669 }
670 $w->xmlEndTag('Table');
671
672 $w->xmlDumpFile($a_basedir . '/' . $a_table . '.xml', false);
673 }
674
675
682 public function buildInsertStatements($a_table, $a_file = "")
683 {
684 if ($a_table == "lng_data") {
685 return;
686 }
687
688 $set = $this->il_db->query("SELECT * FROM " . $this->il_db->quoteIdentifier($a_table));
689 $ins_st = "";
690 $first = true;
691 while ($rec = $this->il_db->fetchAssoc($set)) {
692 $fields = array();
693 $types = array();
694 $values = array();
695 $i_str = array();
696 foreach ($rec as $f => $v) {
697 $fields[] = $f;
698 $types[] = '"' . $this->fields[$f]["type"] . '"';
699 $v = str_replace('\\', '\\\\', $v);
700 $values[] = "'" . str_replace("'", "\'", $v) . "'";
701 $i_str[] = "'" . $f . "' => array('" . $this->fields[$f]["type"] . "', '" . str_replace("'", "\'", $v) . "')";
702 }
703 $fields_str = "(" . implode(",", $fields) . ")";
704 $types_str = "array(" . implode(",", $types) . ")";
705 $values_str = "array(" . implode(",", $values) . ")";
706 $ins_st = "\n" . '$ilDB->insert("' . $a_table . '", array(' . "\n";
707 $ins_st .= implode(", ", $i_str) . "));\n";
708 //$ins_st.= "\t".$fields_str."\n";
709 //$ins_st.= "\t".'VALUES '."(%s".str_repeat(",%s", count($fields) - 1).')"'.",\n";
710 //$ins_st.= "\t".$types_str.','.$values_str.');'."\n";
711
712 if ($a_file == "") {
713 echo $ins_st;
714 } else {
715 fwrite($a_file, $ins_st);
716 }
717 $ins_st = "";
718 }
719 }
720
721
727 public function getHTMLOverview($a_filename = "")
728 {
729 $tpl = new ilTemplate("tpl.db_overview.html", true, true, "Services/Database");
730
731 $this->getTables();
732 $cnt = 1;
733 foreach ($this->tables as $table) {
734 if ($this->checkProcessing($table)) {
735 // create table statement
736 if ($this->addTableToOverview($table, $tpl, $cnt)) {
737 $cnt++;
738 }
739 }
740 }
741
742 $tpl->setVariable("TXT_TITLE", "ILIAS Abstract DB Tables (" . ILIAS_VERSION . ")");
743
744 if ($a_filename == "") {
745 echo $tpl->get();
746 }
747 }
748
749
753 public function addTableToOverview($a_table, $a_tpl, $a_cnt)
754 {
755 $fields = $this->analyzer->getFieldInformation($a_table);
756 $indices = $this->analyzer->getIndicesInformation($a_table);
757 $constraints = $this->analyzer->getConstraintsInformation($a_table);
758 $pk = $this->analyzer->getPrimaryKeyInformation($a_table);
759 $auto = $this->analyzer->getAutoIncrementField($a_table);
760 $has_sequence = $this->analyzer->hasSequence($a_table);
761
762 // table filter
763 if (isset($this->filter["has_sequence"])) {
764 if ((!$has_sequence && $auto == "" && $this->filter["has_sequence"])
765 || (($has_sequence || $auto != "") && !$this->filter["has_sequence"])
766 ) {
767 return false;
768 }
769 }
770
771 // indices
772 $indices_output = false;
773 if (is_array($indices) && count($indices) > 0 && !$this->filter["skip_indices"]) {
774 foreach ($indices as $index => $def) {
775 $f2 = array();
776 foreach ($def["fields"] as $f => $pos) {
777 $f2[] = $f;
778 }
779 $a_tpl->setCurrentBlock("index");
780 $a_tpl->setVariable("VAL_INDEX", $def["name"]);
781 $a_tpl->setVariable("VAL_FIELDS", implode(", ", $f2));
782 $a_tpl->parseCurrentBlock();
783 $indices_output = true;
784 }
785 $a_tpl->setCurrentBlock("index_table");
786 $a_tpl->parseCurrentBlock();
787 }
788
789 // constraints
790 $constraints_output = false;
791 if (is_array($constraints) && count($constraints) > 0 && !$this->filter["skip_constraints"]) {
792 foreach ($constraints as $index => $def) {
793 $f2 = array();
794 foreach ($def["fields"] as $f => $pos) {
795 $f2[] = $f;
796 }
797 $a_tpl->setCurrentBlock("constraint");
798 $a_tpl->setVariable("VAL_CONSTRAINT", $def["name"]);
799 $a_tpl->setVariable("VAL_CTYPE", $def["type"]);
800 $a_tpl->setVariable("VAL_CFIELDS", implode(", ", $f2));
801 $a_tpl->parseCurrentBlock();
802 $constraints_output = true;
803 }
804 $a_tpl->setCurrentBlock("constraint_table");
805 $a_tpl->parseCurrentBlock();
806 }
807
808 // fields
809 $fields_output = false;
810 foreach ($fields as $field => $def) {
811 // field filter
812 if (isset($this->filter["alt_types"])) {
813 if (($def["alt_types"] == "" && $this->filter["alt_types"])
814 || ($def["alt_types"] != "" && !$this->filter["alt_types"])
815 ) {
816 continue;
817 }
818 }
819 if (isset($this->filter["type"])) {
820 if ($def["type"] != $this->filter["type"]) {
821 continue;
822 }
823 }
824 if (isset($this->filter["nativetype"])) {
825 if ($def["nativetype"] != $this->filter["nativetype"]) {
826 continue;
827 }
828 }
829 if (isset($this->filter["unsigned"])) {
830 if ($def["unsigned"] != $this->filter["unsigned"]) {
831 continue;
832 }
833 }
834
835 $a_tpl->setCurrentBlock("field");
836 if (empty($pk["fields"][$field])) {
837 $a_tpl->setVariable("VAL_FIELD", strtolower($field));
838 } else {
839 $a_tpl->setVariable("VAL_FIELD", "<u>" . strtolower($field) . "</u>");
840 }
841 $a_tpl->setVariable("VAL_TYPE", $def["type"]);
842 $a_tpl->setVariable("VAL_LENGTH", (!is_null($def["length"])) ? $def["length"] : "&nbsp;");
843
844 if (strtolower($def["default"]) == "current_timestamp") {
845 //$def["default"] = "0000-00-00 00:00:00";
846 unset($def["default"]);
847 }
848
849 $a_tpl->setVariable("VAL_DEFAULT", (!is_null($def["default"])) ? $def["default"] : "&nbsp;");
850 $a_tpl->setVariable("VAL_NOT_NULL", (!is_null($def["notnull"])) ? (($def["notnull"]) ? "true" : "false") : "&nbsp;");
851 $a_tpl->setVariable("VAL_FIXED", (!is_null($def["fixed"])) ? (($def["fixed"]) ? "true" : "false") : "&nbsp;");
852 $a_tpl->setVariable("VAL_UNSIGNED", (!is_null($def["unsigned"])) ? (($def["unsigned"]) ? "true" : "false") : "&nbsp;");
853 $a_tpl->setVariable("VAL_ALTERNATIVE_TYPES", ($def["alt_types"] != "") ? $def["alt_types"] : "&nbsp;");
854 $a_tpl->setVariable("VAL_NATIVETYPE", ($def["nativetype"] != "") ? $def["nativetype"] : "&nbsp;");
855 $a_tpl->parseCurrentBlock();
856 $fields_output = true;
857 }
858
859 if ($fields_output) {
860 $a_tpl->setCurrentBlock("field_table");
861 $a_tpl->parseCurrentBlock();
862 }
863
864 // table information
865 if ($indices_output || $fields_output || $constraints_output) {
866 $a_tpl->setCurrentBlock("table");
867 $a_tpl->setVariable("TXT_TABLE_NAME", strtolower($a_table));
868 if ($has_sequence || $auto != "") {
869 $a_tpl->setVariable("TXT_SEQUENCE", "Has Sequence");
870 } else {
871 $a_tpl->setVariable("TXT_SEQUENCE", "No Sequence");
872 }
873 $a_tpl->setVariable("VAL_CNT", (int) $a_cnt);
874 $a_tpl->parseCurrentBlock();
875
876 return true;
877 }
878
879 return false;
880 }
881
882
892 protected function shortenText($table, $field, $a_value, $a_size)
893 {
894 global $DIC;
895 $ilLogger = $DIC->logger()->root();
896
897 if ($this->getTargetEncoding() == 'UTF-8') {
898 return $a_value;
899 }
900 // Convert to target encoding
901 $shortened = mb_convert_encoding($a_value, $this->getTargetEncoding(), 'UTF-8');
902 // Shorten
903 include_once './Services/Utilities/classes/class.ilStr.php';
904 $shortened = ilStr::shortenText($shortened, 0, $a_size, $this->getTargetEncoding());
905 // Convert back to UTF-8
906 $shortened = mb_convert_encoding($shortened, 'UTF-8', $this->getTargetEncoding());
907
908 if (strlen($a_value) != strlen($shortened)) {
909 $ilLogger->log('Table : ' . $table);
910 $ilLogger->log('Field : ' . $field);
911 $ilLogger->log('Type : ' . $this->fields[$field]['type']);
912 $ilLogger->log('Length : ' . $this->fields[$field]['length']);
913 $ilLogger->log('Before : ' . $a_value);
914 $ilLogger->log('Shortened : ' . $shortened);
915 $ilLogger->log('Strlen Before: ' . strlen($a_value));
916 $ilLogger->log('Strlen After : ' . strlen($shortened));
917 }
918
919 return $shortened;
920 }
921}
$tpl
Definition: ilias.php:10
$path
Definition: aliased.php:25
An exception for terminatinating execution or to throw for unit testing.
This class gives all kind of DB information using the database manager and reverse module.
static shortenText($a_string, $a_start_pos, $a_num_bytes, $a_encoding='UTF-8')
Shorten text to the given number of bytes.
special template class to simplify handling of ITX/PEAR
XML writer class.
$def
Definition: croninfo.php:21
$i
Definition: disco.tpl.php:19
$w
$r
Definition: example_031.php:79
const ILIAS_VERSION
$index
Definition: metadata.php:60
$row
$query
if(empty($password)) $table
Definition: pwgen.php:24
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
global $ilDB
$values
$errors fields
Definition: imgupload.php:51
$start
Definition: bench.php:8
$rows
Definition: xhr_table.php:10