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