1<?php 2 3/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */ 4 5/** 6 * This class provides methods for building a DB generation script, 7 * getting a full overview on abstract table definitions and more... 8 * 9 * @author Alex Killing <alex.killing@gmx.de> 10 * @version $Id: class.ilDBUpdate.php 18649 2009-01-21 09:59:23Z akill $ 11 * @ingroup ServicesDatabase 12 */ 13class ilDBGenerator 14{ 15 16 /** 17 * @var string 18 */ 19 protected $target_encoding = 'UTF-8'; 20 /** 21 * @var array 22 */ 23 protected $whitelist = array(); 24 /** 25 * @var array 26 */ 27 protected $blacklist = array(); 28 /** 29 * @var array 30 */ 31 protected $tables = array(); 32 /** 33 * @var array 34 */ 35 protected $filter = array(); 36 37 38 /** 39 * Constructor 40 */ 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 55 /** 56 * @return array 57 * @deprecated abstraction_progress is no longer used in ILIAS 58 */ 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 127 /** 128 * Set the desired target encoding 129 * If the target encoding os different from UTF-8 130 * all text values will be shortened to length of 131 * of the current text field 132 * 133 * E.g: 134 * il_meta_keyword keyword(4000) target encoding: UTF16 135 * 136 * => 137 * <code> 138 * $value = mb_convert_encoding($value,'UTF-8','UTF-16'); 139 * $value = mb_strcut($value,0,4000,'UTF16'); 140 * $value = mb_convert_encoding($value,'UTF-16','UTF-8'); 141 * </code> 142 * 143 * 144 * @param object $a_encoding 145 * @return 146 */ 147 public function setTargetEncoding($a_encoding) 148 { 149 $this->target_encoding = $a_encoding; 150 } 151 152 153 /** 154 * Returns the target encoding 155 * 156 * @return string 157 */ 158 public function getTargetEncoding() 159 { 160 return $this->target_encoding; 161 } 162 163 164 /** 165 * Set Table Black List. 166 * (Tables that should not be included in the processing) 167 * 168 * @param array $a_blacklist Table Black List 169 */ 170 public function setBlackList($a_blacklist) 171 { 172 $this->blacklist = $a_blacklist; 173 } 174 175 176 /** 177 * Get Table Black List. 178 * 179 * @return array Table Black List 180 */ 181 public function getBlackList() 182 { 183 return $this->blacklist; 184 } 185 186 187 /** 188 * Set Table White List. 189 * Per default all tables are included in the processing. If a white 190 * list ist provided, only them will be used. 191 * 192 * @param array $a_whitelist Table White List 193 */ 194 public function setWhiteList($a_whitelist) 195 { 196 $this->whitelist = $a_whitelist; 197 } 198 199 200 /** 201 * Get Table White List. 202 * 203 * @return array Table White List 204 */ 205 public function getWhiteList() 206 { 207 return $this->whitelist; 208 } 209 210 211 /** 212 * @param $a_filter 213 * @param $a_value 214 */ 215 public function setFilter($a_filter, $a_value) 216 { 217 $this->filter[$a_filter] = $a_value; 218 } 219 220 221 /** 222 * @return array 223 */ 224 public function getTables() 225 { 226 $r = $this->manager->listTables(); 227 $this->tables = $r; 228 229 return $this->tables; 230 } 231 232 233 /** 234 * Check whether a table should be processed or not 235 */ 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 286 /** 287 * Build DB generation script 288 * 289 * @param string output filename, if no filename is given, script is echoed 290 */ 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 378 /** 379 * Build CreateTable statement 380 * 381 * @param string table name 382 * @param file file resource or empty string 383 */ 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 429 /** 430 * Build AddPrimaryKey statement 431 * 432 * @param string table name 433 * @param file file resource or empty string 434 */ 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 458 /** 459 * Build AddIndex statements 460 * 461 * @param string table name 462 * @param file file resource or empty string 463 */ 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 494 /** 495 * Build AddUniqueConstraint statements 496 * 497 * @param string table name 498 * @param file file resource or empty string 499 */ 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 525 /** 526 * Build CreateSequence statement 527 * 528 * @param string table name 529 * @param file file resource or empty string 530 */ 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 546 /** 547 * Build CreateSequence statement (if not belonging to table) 548 * 549 * @param file file resource or empty string 550 */ 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 574 /** 575 * Write seerialized insert data to array 576 * 577 * @param object $a_table 578 * @param object $a_basedir 579 * @return 580 */ 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 635 /** 636 * 637 * @param object $a_table 638 * @param object $a_file [optional] 639 * @return 640 */ 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 676 /** 677 * Build Insert statements 678 * 679 * @param string table name 680 * @param file file resource or empty string 681 */ 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 722 /** 723 * Get table definition overview in HTML 724 * 725 * @param string output filename, if no filename is given, script is echoed 726 */ 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 750 /** 751 * Add table to overview template 752 */ 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"] : " "); 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"] : " "); 850 $a_tpl->setVariable("VAL_NOT_NULL", (!is_null($def["notnull"])) ? (($def["notnull"]) ? "true" : "false") : " "); 851 $a_tpl->setVariable("VAL_FIXED", (!is_null($def["fixed"])) ? (($def["fixed"]) ? "true" : "false") : " "); 852 $a_tpl->setVariable("VAL_UNSIGNED", (!is_null($def["unsigned"])) ? (($def["unsigned"]) ? "true" : "false") : " "); 853 $a_tpl->setVariable("VAL_ALTERNATIVE_TYPES", ($def["alt_types"] != "") ? $def["alt_types"] : " "); 854 $a_tpl->setVariable("VAL_NATIVETYPE", ($def["nativetype"] != "") ? $def["nativetype"] : " "); 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 883 /** 884 * Shorten text depending on target encoding 885 * 886 * @param string $table 887 * @param string $field 888 * @param string $a_value 889 * @param int $a_size 890 * @return string 891 */ 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} 922