1<?php 2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4/** 5* Class ilGlossaryTerm 6* 7* @author Alex Killing <alex.killing@gmx.de> 8* @version $Id$ 9* 10* @ingroup ModulesGlossary 11*/ 12class ilGlossaryTerm 13{ 14 /** 15 * @var ilDB 16 */ 17 protected $db; 18 19 public $lng; 20 public $tpl; 21 22 public $id; 23 public $glossary; 24 public $term; 25 public $language; 26 public $glo_id; 27 public $import_id; 28 29 /** 30 * Constructor 31 * @access public 32 */ 33 public function __construct($a_id = 0) 34 { 35 global $DIC; 36 37 $this->db = $DIC->database(); 38 $lng = $DIC->language(); 39 $tpl = $DIC["tpl"]; 40 41 $this->lng = $lng; 42 $this->tpl = $tpl; 43 44 $this->id = $a_id; 45 $this->type = "term"; 46 if ($a_id != 0) { 47 $this->read(); 48 } 49 } 50 51 /** 52 * read glossary term data 53 */ 54 public function read() 55 { 56 $ilDB = $this->db; 57 58 $q = "SELECT * FROM glossary_term WHERE id = " . 59 $ilDB->quote($this->id, "integer"); 60 $term_set = $ilDB->query($q); 61 $term_rec = $ilDB->fetchAssoc($term_set); 62 63 $this->setTerm($term_rec["term"]); 64 $this->setImportId($term_rec["import_id"]); 65 $this->setLanguage($term_rec["language"]); 66 $this->setGlossaryId($term_rec["glo_id"]); 67 } 68 69 /** 70 * get current term id for import id (static) 71 * 72 * @param int $a_import_id import id 73 * 74 * @return int id 75 */ 76 public static function _getIdForImportId($a_import_id) 77 { 78 global $DIC; 79 80 $ilDB = $DIC->database(); 81 82 if ($a_import_id == "") { 83 return 0; 84 } 85 86 $q = "SELECT * FROM glossary_term WHERE import_id = " . 87 $ilDB->quote($a_import_id, "text") . 88 " ORDER BY create_date DESC"; 89 $term_set = $ilDB->query($q); 90 while ($term_rec = $ilDB->fetchAssoc($term_set)) { 91 $glo_id = ilGlossaryTerm::_lookGlossaryID($term_rec["id"]); 92 93 $ref_ids = ilObject::_getAllReferences($glo_id); // will be 0 if import of lm is in progress (new import) 94 if (count($ref_ids) == 0 || ilObject::_hasUntrashedReference($glo_id)) { 95 return $term_rec["id"]; 96 } 97 } 98 99 return 0; 100 } 101 102 103 /** 104 * checks wether a glossary term with specified id exists or not 105 * 106 * @param int $id id 107 * 108 * @return boolean true, if glossary term exists 109 */ 110 public static function _exists($a_id) 111 { 112 global $DIC; 113 114 $ilDB = $DIC->database(); 115 116 include_once("./Services/Link/classes/class.ilInternalLink.php"); 117 if (is_int(strpos($a_id, "_"))) { 118 $a_id = ilInternalLink::_extractObjIdOfTarget($a_id); 119 } 120 121 $q = "SELECT * FROM glossary_term WHERE id = " . 122 $ilDB->quote($a_id, "integer"); 123 $obj_set = $ilDB->query($q); 124 if ($obj_rec = $ilDB->fetchAssoc($obj_set)) { 125 return true; 126 } else { 127 return false; 128 } 129 } 130 131 132 /** 133 * set glossary term id (= glossary item id) 134 * 135 * @param int $a_id glossary term id 136 */ 137 public function setId($a_id) 138 { 139 $this->id = $a_id; 140 } 141 142 143 /** 144 * get term id (= glossary item id) 145 * 146 * @return int glossary term id 147 */ 148 public function getId() 149 { 150 return $this->id; 151 } 152 153 /** 154 * set glossary object 155 * 156 * @param object $a_glossary glossary object 157 */ 158 public function setGlossary(&$a_glossary) 159 { 160 $this->glossary = $a_glossary; 161 $this->setGlossaryId($a_glossary->getId()); 162 } 163 164 165 /** 166 * set glossary id 167 * 168 * @param int $a_glo_id glossary id 169 */ 170 public function setGlossaryId($a_glo_id) 171 { 172 $this->glo_id = $a_glo_id; 173 } 174 175 176 /** 177 * get glossary id 178 * 179 * @return int glossary id 180 */ 181 public function getGlossaryId() 182 { 183 return $this->glo_id; 184 } 185 186 187 /** 188 * set term 189 * 190 * @param string $a_term term 191 */ 192 public function setTerm($a_term) 193 { 194 $this->term = $a_term; 195 } 196 197 198 /** 199 * get term 200 * 201 * @return string term 202 */ 203 public function getTerm() 204 { 205 return $this->term; 206 } 207 208 209 /** 210 * set language 211 * 212 * @param string $a_language two letter language code 213 */ 214 public function setLanguage($a_language) 215 { 216 $this->language = $a_language; 217 } 218 219 /** 220 * get language 221 * @return string two letter language code 222 */ 223 public function getLanguage() 224 { 225 return $this->language; 226 } 227 228 229 /** 230 * set import id 231 */ 232 public function setImportId($a_import_id) 233 { 234 $this->import_id = $a_import_id; 235 } 236 237 238 /** 239 * get import id 240 */ 241 public function getImportId() 242 { 243 return $this->import_id; 244 } 245 246 247 /** 248 * create new glossary term 249 */ 250 public function create() 251 { 252 $ilDB = $this->db; 253 254 $this->setId($ilDB->nextId("glossary_term")); 255 $ilDB->manipulate("INSERT INTO glossary_term (id, glo_id, term, language, import_id, create_date, last_update)" . 256 " VALUES (" . 257 $ilDB->quote($this->getId(), "integer") . ", " . 258 $ilDB->quote($this->getGlossaryId(), "integer") . ", " . 259 $ilDB->quote($this->term, "text") . ", " . 260 $ilDB->quote($this->language, "text") . "," . 261 $ilDB->quote($this->getImportId(), "text") . "," . 262 $ilDB->now() . ", " . 263 $ilDB->now() . ")"); 264 } 265 266 267 /** 268 * delete glossary term (and all its definition objects) 269 */ 270 public function delete() 271 { 272 $ilDB = $this->db; 273 274 require_once("./Modules/Glossary/classes/class.ilGlossaryDefinition.php"); 275 $defs = ilGlossaryDefinition::getDefinitionList($this->getId()); 276 foreach ($defs as $def) { 277 $def_obj = new ilGlossaryDefinition($def["id"]); 278 $def_obj->delete(); 279 } 280 281 // delete term references 282 include_once("./Modules/Glossary/classes/class.ilGlossaryTermReferences.php"); 283 ilGlossaryTermReferences::deleteReferencesOfTerm($this->getId()); 284 285 // delete glossary_term record 286 $ilDB->manipulate("DELETE FROM glossary_term " . 287 " WHERE id = " . $ilDB->quote($this->getId(), "integer")); 288 } 289 290 291 /** 292 * update glossary term 293 */ 294 public function update() 295 { 296 $ilDB = $this->db; 297 298 $ilDB->manipulate("UPDATE glossary_term SET " . 299 " glo_id = " . $ilDB->quote($this->getGlossaryId(), "integer") . ", " . 300 " term = " . $ilDB->quote($this->getTerm(), "text") . ", " . 301 " import_id = " . $ilDB->quote($this->getImportId(), "text") . ", " . 302 " language = " . $ilDB->quote($this->getLanguage(), "text") . ", " . 303 " last_update = " . $ilDB->now() . " " . 304 " WHERE id = " . $ilDB->quote($this->getId(), "integer")); 305 } 306 307 /** 308 * get glossary id form term id 309 */ 310 public static function _lookGlossaryID($term_id) 311 { 312 global $DIC; 313 314 $ilDB = $DIC->database(); 315 316 $query = "SELECT * FROM glossary_term WHERE id = " . 317 $ilDB->quote($term_id, "integer"); 318 $obj_set = $ilDB->query($query); 319 $obj_rec = $ilDB->fetchAssoc($obj_set); 320 321 return $obj_rec["glo_id"]; 322 } 323 324 /** 325 * get glossary term 326 */ 327 public static function _lookGlossaryTerm($term_id) 328 { 329 global $DIC; 330 331 $ilDB = $DIC->database(); 332 333 $query = "SELECT * FROM glossary_term WHERE id = " . 334 $ilDB->quote($term_id, "integer"); 335 $obj_set = $ilDB->query($query); 336 $obj_rec = $ilDB->fetchAssoc($obj_set); 337 338 return $obj_rec["term"]; 339 } 340 341 /** 342 * lookup term language 343 */ 344 public static function _lookLanguage($term_id) 345 { 346 global $DIC; 347 348 $ilDB = $DIC->database(); 349 350 $query = "SELECT * FROM glossary_term WHERE id = " . 351 $ilDB->quote($term_id, "integer"); 352 $obj_set = $ilDB->query($query); 353 $obj_rec = $ilDB->fetchAssoc($obj_set); 354 355 return $obj_rec["language"]; 356 } 357 358 /** 359 * Get all terms for given set of glossary ids. 360 * 361 * @param integer/array array of glossary ids for meta glossaries 362 * @param string searchstring 363 * @param string first letter 364 * @return array array of terms 365 */ 366 public static function getTermList( 367 $a_glo_ref_id, 368 $searchterm = "", 369 $a_first_letter = "", 370 $a_def = "", 371 $a_tax_node = 0, 372 $a_add_amet_fields = false, 373 array $a_amet_filter = null, 374 $a_include_references = false 375 ) { 376 global $DIC; 377 378 if (is_array($a_glo_ref_id)) { 379 $a_glo_id = array_map(function ($id) { 380 return ilObject::_lookupObjectId($id); 381 }, $a_glo_ref_id); 382 } else { 383 $a_glo_id = ilObject::_lookupObjectId($a_glo_ref_id); 384 } 385 $ilDB = $DIC->database(); 386 387 $join = $in = ""; 388 389 $terms = array(); 390 391 // get all term ids under taxonomy node (if given) 392 if ($a_tax_node > 1) { 393 include_once("./Services/Taxonomy/classes/class.ilObjTaxonomy.php"); 394 $tax_ids = ilObjTaxonomy::getUsageOfObject($a_glo_id); 395 if (count($tax_ids) > 0) { 396 $items = ilObjTaxonomy::getSubTreeItems("glo", $a_glo_id, "term", $tax_ids[0], $a_tax_node); 397 $sub_tree_ids = array(); 398 foreach ($items as $i) { 399 $sub_tree_ids[] = $i["item_id"]; 400 } 401 $in = " AND " . $ilDB->in("gt.id", $sub_tree_ids, false, "integer"); 402 } 403 } 404 405 if ($a_def != "") { 406 // meta glossary? 407 if (is_array($a_glo_id)) { 408 $glo_where = $ilDB->in("page_object.parent_id", $a_glo_id, false, "integer"); 409 } else { 410 $glo_where = " page_object.parent_id = " . $ilDB->quote($a_glo_id, "integer"); 411 } 412 413 $join = " JOIN glossary_definition gd ON (gd.term_id = gt.id)" . 414 " JOIN page_object ON (" . 415 $glo_where . 416 " AND page_object.parent_type = " . $ilDB->quote("gdf", "text") . 417 " AND page_object.page_id = gd.id" . 418 " AND " . $ilDB->like("page_object.content", "text", "%" . $a_def . "%") . 419 ")"; 420 } 421 422 $searchterm = (!empty($searchterm)) 423 ? " AND " . $ilDB->like("term", "text", "%" . $searchterm . "%") . " " 424 : ""; 425 426 if ($a_first_letter != "") { 427 $searchterm .= " AND " . $ilDB->upper($ilDB->substr("term", 1, 1)) . " = " . $ilDB->upper($ilDB->quote($a_first_letter, "text")) . " "; 428 } 429 430 // include references 431 $where_glo_id_or = ""; 432 if ($a_include_references) { 433 $join .= " LEFT JOIN glo_term_reference tr ON (gt.id = tr.term_id) "; 434 if (is_array($a_glo_id)) { 435 $where_glo_id_or = " OR " . $ilDB->in("tr.glo_id", $a_glo_id, false, "integer"); 436 } else { 437 $where_glo_id_or = " OR tr.glo_id = " . $ilDB->quote($a_glo_id, "integer"); 438 } 439 } 440 441 // meta glossary 442 if (is_array($a_glo_id)) { 443 $where = "(" . $ilDB->in("gt.glo_id", $a_glo_id, false, "integer") . $where_glo_id_or . ")"; 444 } else { 445 $where = "(gt.glo_id = " . $ilDB->quote($a_glo_id, "integer") . $where_glo_id_or . ")"; 446 } 447 448 $where .= $in; 449 450 451 $q = "SELECT DISTINCT(gt.term), gt.id, gt.glo_id, gt.language FROM glossary_term gt " . $join . " WHERE " . $where . $searchterm . " ORDER BY term"; 452 453 //echo $q; exit; 454 455 $term_set = $ilDB->query($q); 456 $glo_ids = array(); 457 while ($term_rec = $ilDB->fetchAssoc($term_set)) { 458 $terms[] = array("term" => $term_rec["term"], 459 "language" => $term_rec["language"], "id" => $term_rec["id"], "glo_id" => $term_rec["glo_id"]); 460 $glo_ids[] = $term_rec["glo_id"]; 461 } 462 463 // add advanced metadata 464 if (($a_add_amet_fields || is_array($a_amet_filter)) && !is_array($a_glo_ref_id)) { 465 include_once("./Services/AdvancedMetaData/classes/class.ilAdvancedMDValues.php"); 466 $terms = ilAdvancedMDValues::queryForRecords($a_glo_ref_id, "glo", "term", $glo_ids, "term", $terms, "glo_id", "id", $a_amet_filter); 467 } 468 return $terms; 469 } 470 471 /** 472 * Get all terms for given set of glossary ids. 473 * 474 * @param integer/array array of glossary ids for meta glossaries 475 * @param string searchstring 476 * @param string first letter 477 * @return array array of terms 478 */ 479 public static function getFirstLetters($a_glo_id, $a_tax_node = 0) 480 { 481 global $DIC; 482 483 $ilDB = $DIC->database(); 484 485 $terms = array(); 486 487 // meta glossary 488 if (is_array($a_glo_id)) { 489 $where = $ilDB->in("glo_id", $a_glo_id, false, "integer"); 490 } else { 491 $where = " glo_id = " . $ilDB->quote($a_glo_id, "integer") . " "; 492 493 // get all term ids under taxonomy node (if given) 494 if ($a_tax_node > 1) { 495 include_once("./Services/Taxonomy/classes/class.ilObjTaxonomy.php"); 496 $tax_ids = ilObjTaxonomy::getUsageOfObject($a_glo_id); 497 if (count($tax_ids) > 0) { 498 $items = ilObjTaxonomy::getSubTreeItems("glo", $a_glo_id, "term", $tax_ids[0], $a_tax_node); 499 $sub_tree_ids = array(); 500 foreach ($items as $i) { 501 $sub_tree_ids[] = $i["item_id"]; 502 } 503 $in = " AND " . $ilDB->in("id", $sub_tree_ids, false, "integer"); 504 } 505 } 506 507 $where .= $in; 508 } 509 510 $q = "SELECT DISTINCT " . $ilDB->upper($ilDB->substr("term", 1, 1)) . " let FROM glossary_term WHERE " . $where . " ORDER BY let"; 511 $let_set = $ilDB->query($q); 512 513 $lets = array(); 514 while ($let_rec = $ilDB->fetchAssoc($let_set)) { 515 $let[$let_rec["let"]] = $let_rec["let"]; 516 } 517 return $let; 518 } 519 520 /** 521 * export xml 522 */ 523 public function exportXML(&$a_xml_writer, $a_inst) 524 { 525 $attrs = array(); 526 $attrs["Language"] = $this->getLanguage(); 527 $attrs["Id"] = "il_" . IL_INST_ID . "_git_" . $this->getId(); 528 $a_xml_writer->xmlStartTag("GlossaryItem", $attrs); 529 530 $attrs = array(); 531 $a_xml_writer->xmlElement("GlossaryTerm", $attrs, $this->getTerm()); 532 533 $defs = ilGlossaryDefinition::getDefinitionList($this->getId()); 534 535 foreach ($defs as $def) { 536 $definition = new ilGlossaryDefinition($def["id"]); 537 $definition->exportXML($a_xml_writer, $a_inst); 538 } 539 540 $a_xml_writer->xmlEndTag("GlossaryItem"); 541 } 542 543 /** 544 * Get number of usages 545 * 546 * @param int term id 547 * @return int number of usages 548 */ 549 public static function getNumberOfUsages($a_term_id) 550 { 551 return count(ilGlossaryTerm::getUsages($a_term_id)); 552 } 553 554 /** 555 * Get number of usages 556 * 557 * @param int term id 558 * @return int number of usages 559 */ 560 public static function getUsages($a_term_id) 561 { 562 include_once("./Services/Link/classes/class.ilInternalLink.php"); 563 $usages = (ilInternalLink::_getSourcesOfTarget("git", $a_term_id, 0)); 564 565 include_once("./Modules/Glossary/classes/class.ilGlossaryTermReferences.php"); 566 foreach (ilGlossaryTermReferences::lookupReferencesOfTerm($a_term_id) as $glo_id) { 567 $usages["glo:termref:" . $glo_id . ":-"] = array( 568 "type" => "glo:termref", 569 "id" => $glo_id, 570 "lang" => "-" 571 ); 572 } 573 574 return $usages; 575 } 576 577 /** 578 * Copy a term to a glossary 579 * 580 * @param 581 * @return 582 */ 583 public static function _copyTerm($a_term_id, $a_glossary_id) 584 { 585 $old_term = new ilGlossaryTerm($a_term_id); 586 587 // copy the term 588 $new_term = new ilGlossaryTerm(); 589 $new_term->setTerm($old_term->getTerm()); 590 $new_term->setLanguage($old_term->getLanguage()); 591 $new_term->setGlossaryId($a_glossary_id); 592 $new_term->create(); 593 594 // copy the definitions 595 include_once("./Modules/Glossary/classes/class.ilGlossaryDefinition.php"); 596 $def_list = ilGlossaryDefinition::getDefinitionList($a_term_id); 597 foreach ($def_list as $def) { 598 $old_def = new ilGlossaryDefinition($def["id"]); 599 600 $new_def = new ilGlossaryDefinition(); 601 $new_def->setShortText($old_def->getShortText()); 602 $new_def->setNr($old_def->getNr()); 603 $new_def->setTermId($new_term->getId()); 604 $new_def->create(); 605 606 // copy meta data 607 include_once("Services/MetaData/classes/class.ilMD.php"); 608 $md = new ilMD( 609 $old_term->getGlossaryId(), 610 $old_def->getPageObject()->getId(), 611 $old_def->getPageObject()->getParentType() 612 ); 613 $new_md = $md->cloneMD( 614 $a_glossary_id, 615 $new_def->getPageObject()->getId(), 616 $old_def->getPageObject()->getParentType() 617 ); 618 619 620 $new_page = $new_def->getPageObject(); 621 $old_def->getPageObject()->copy($new_page->getId(), $new_page->getParentType(), $new_page->getParentId(), true); 622 623 // page content 624 //$new_def->getPageObject()->setXMLContent($old_def->getPageObject()->copyXmlContent(true)); 625 //$new_def->getPageObject()->buildDom(); 626 //$new_def->getPageObject()->update(); 627 } 628 629 // adv metadata 630 include_once('Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php'); 631 include_once('Services/AdvancedMetaData/classes/class.ilAdvancedMDFieldDefinition.php'); 632 $old_recs = ilAdvancedMDRecord::_getSelectedRecordsByObject("glo", $old_term->getGlossaryId(), "term"); 633 $new_recs = ilAdvancedMDRecord::_getSelectedRecordsByObject("glo", $a_glossary_id, "term"); 634 foreach ($old_recs as $old_record_obj) { 635 reset($new_recs); 636 foreach ($new_recs as $new_record_obj) { 637 if ($old_record_obj->getRecordId() == $new_record_obj->getRecordId()) { 638 foreach (ilAdvancedMDFieldDefinition::getInstancesByRecordId($old_record_obj->getRecordId()) as $def) { 639 // now we need to copy $def->getFieldId() values from old term to new term 640 // how? 641 // clone values 642 643 $source_primary = array("obj_id" => array("integer", $old_term->getGlossaryId())); 644 $source_primary["sub_type"] = array("text", "term"); 645 $source_primary["sub_id"] = array("integer", $old_term->getId()); 646 $source_primary["field_id"] = array("integer", $def->getFieldId()); 647 $target_primary = array("obj_id" => array("integer", $new_term->getGlossaryId())); 648 $target_primary["sub_type"] = array("text", "term"); 649 $target_primary["sub_id"] = array("integer", $new_term->getId()); 650 651 ilADTFactory::getInstance()->initActiveRecordByType(); 652 $has_cloned = ilADTActiveRecordByType::cloneByPrimary( 653 "adv_md_values", 654 array( 655 "obj_id" => "integer", 656 "sub_type" => "text", 657 "sub_id" => "integer", 658 "field_id" => "integer" 659 ), 660 $source_primary, 661 $target_primary, 662 array("disabled" => "integer") 663 ); 664 } 665 } 666 } 667 } 668 669 670 return $new_term->getId(); 671 } 672 673 /** 674 * Get terms of glossary 675 * 676 * @param 677 * @return 678 */ 679 public static function getTermsOfGlossary($a_glo_id) 680 { 681 global $DIC; 682 683 $ilDB = $DIC->database(); 684 685 $set = $ilDB->query( 686 "SELECT id FROM glossary_term WHERE " . 687 " glo_id = " . $ilDB->quote($a_glo_id, "integer") 688 ); 689 $ids = array(); 690 while ($rec = $ilDB->fetchAssoc($set)) { 691 $ids[] = $rec["id"]; 692 } 693 return $ids; 694 } 695} 696