1<?php 2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4define('UDF_TYPE_TEXT', 1); 5define('UDF_TYPE_SELECT', 2); 6define('UDF_TYPE_WYSIWYG', 3); 7define('UDF_NO_VALUES', 1); 8define('UDF_DUPLICATE_VALUES', 2); 9 10 11/** 12* Additional user data fields definition 13* 14* @author Stefan Meyer <meyer@leifos.com> 15* 16* @version $Id$ 17* @ingroup ServicesUser 18*/ 19class ilUserDefinedFields 20{ 21 public $db = null; 22 public $definitions = array(); 23 24 private $field_visible_registration = 0; 25 26 /** 27 * Constructor is private -> use getInstance 28 * These definition are used e.g in User XML import. 29 * To avoid instances of this class for every user object during import, 30 * it caches this object in a singleton. 31 * 32 */ 33 private function __construct() 34 { 35 global $DIC; 36 37 $ilDB = $DIC['ilDB']; 38 39 $this->db = &$ilDB; 40 41 $this->__read(); 42 } 43 44 /** 45 * Get instance 46 * @return ilUserDefinedFields 47 */ 48 public static function _getInstance() 49 { 50 static $udf = null; 51 52 if (!is_object($udf)) { 53 return $udf = new ilUserDefinedFields(); 54 } 55 return $udf; 56 } 57 58 public function fetchFieldIdFromImportId($a_import_id) 59 { 60 global $DIC; 61 62 $ilSetting = $DIC['ilSetting']; 63 64 if (!strlen($a_import_id)) { 65 return 0; 66 } 67 $parts = explode('_', $a_import_id); 68 69 if ($parts[0] != 'il') { 70 return 0; 71 } 72 if ($parts[1] != $ilSetting->get('inst_id', 0)) { 73 return 0; 74 } 75 if ($parts[2] != 'udf') { 76 return 0; 77 } 78 if ($parts[3]) { 79 // Check if field exists 80 if (is_array($this->definitions["$parts[3]"])) { 81 return $parts[3]; 82 } 83 } 84 return 0; 85 } 86 public function fetchFieldIdFromName($a_name) 87 { 88 foreach ($this->definitions as $definition) { 89 if ($definition['field_name'] == $a_name) { 90 return $definition['field_id']; 91 } 92 } 93 return 0; 94 } 95 96 /** 97 * @return array 98 */ 99 public function getDefinitions() 100 { 101 return $this->definitions ? $this->definitions : array(); 102 } 103 104 public function getDefinition($a_id) 105 { 106 return is_array($this->definitions[$a_id]) ? $this->definitions[$a_id] : array(); 107 } 108 109 public function getVisibleDefinitions() 110 { 111 foreach ($this->definitions as $id => $definition) { 112 if ($definition['visible']) { 113 $visible_definition[$id] = $definition; 114 } 115 } 116 return $visible_definition ? $visible_definition : array(); 117 } 118 119 public function getLocalUserAdministrationDefinitions() 120 { 121 foreach ($this->definitions as $id => $definition) { 122 if ($definition['visib_lua']) { 123 $visible_definition[$id] = $definition; 124 } 125 } 126 return $visible_definition ? $visible_definition : array(); 127 } 128 129 public function getChangeableLocalUserAdministrationDefinitions() 130 { 131 foreach ($this->definitions as $id => $definition) { 132 if ($definition['changeable_lua']) { 133 $visible_definition[$id] = $definition; 134 } 135 } 136 return $visible_definition ? $visible_definition : array(); 137 } 138 139 public function getRegistrationDefinitions() 140 { 141 foreach ($this->definitions as $id => $definition) { 142 if ($definition['visib_reg']) { 143 $visible_definition[$id] = $definition; 144 } 145 } 146 return $visible_definition ? $visible_definition : array(); 147 } 148 149 public function getSearchableDefinitions() 150 { 151 foreach ($this->definitions as $id => $definition) { 152 if ($definition['searchable']) { 153 $searchable_definition[$id] = $definition; 154 } 155 } 156 return $searchable_definition ? $searchable_definition : array(); 157 } 158 159 public function getRequiredDefinitions() 160 { 161 foreach ($this->definitions as $id => $definition) { 162 if ($definition['required']) { 163 $required_definition[$id] = $definition; 164 } 165 } 166 return $required_definition ? $required_definition : array(); 167 } 168 169 /** 170 * get 171 * 172 * @access public 173 * @param 174 * 175 */ 176 public function getCourseExportableFields() 177 { 178 foreach ($this->definitions as $id => $definition) { 179 if ($definition['course_export']) { 180 $cexp_definition[$id] = $definition; 181 } 182 } 183 return $cexp_definition ? $cexp_definition : array(); 184 } 185 186 /** 187 * get fields visible in groups 188 * 189 * @access public 190 * @param 191 * 192 */ 193 public function getGroupExportableFields() 194 { 195 foreach ($this->definitions as $id => $definition) { 196 if ($definition['group_export']) { 197 $cexp_definition[$id] = $definition; 198 } 199 } 200 return $cexp_definition ? $cexp_definition : array(); 201 } 202 203 /** 204 * Get exportable field 205 * @param int $a_obj_id 206 * @return 207 */ 208 public function getExportableFields($a_obj_id) 209 { 210 if (ilObject::_lookupType($a_obj_id) == 'crs') { 211 return $this->getCourseExportableFields(); 212 } 213 if (ilObject::_lookupType($a_obj_id) == 'grp') { 214 return $this->getGroupExportableFields(); 215 } 216 return array(); 217 } 218 219 220 public function setFieldName($a_name) 221 { 222 $this->field_name = $a_name; 223 } 224 public function getFieldName() 225 { 226 return $this->field_name; 227 } 228 public function setFieldType($a_type) 229 { 230 $this->field_type = $a_type; 231 } 232 233 public function isPluginType() 234 { 235 if (!$this->field_type) { 236 return false; 237 } 238 switch ($this->field_type) { 239 case UDF_TYPE_TEXT: 240 case UDF_TYPE_SELECT: 241 case UDF_TYPE_WYSIWYG: 242 return false; 243 244 default: 245 return true; 246 } 247 } 248 249 public function getFieldType() 250 { 251 return $this->field_type; 252 } 253 public function setFieldValues($a_values) 254 { 255 $this->field_values = array(); 256 foreach ($a_values as $value) { 257 if (strlen($value)) { 258 $this->field_values[] = $value; 259 } 260 } 261 } 262 public function getFieldValues() 263 { 264 return $this->field_values ? $this->field_values : array(); 265 } 266 267 public function enableVisible($a_visible) 268 { 269 $this->field_visible = $a_visible; 270 } 271 public function enabledVisible() 272 { 273 return $this->field_visible; 274 } 275 public function enableVisibleLocalUserAdministration($a_visible) 276 { 277 $this->field_visib_lua = $a_visible; 278 } 279 public function enabledVisibleLocalUserAdministration() 280 { 281 return $this->field_visib_lua; 282 } 283 public function enableChangeable($a_changeable) 284 { 285 $this->field_changeable = $a_changeable; 286 } 287 public function enabledChangeable() 288 { 289 return $this->field_changeable; 290 } 291 public function enableChangeableLocalUserAdministration($a_changeable) 292 { 293 $this->field_changeable_lua = $a_changeable; 294 } 295 public function enabledChangeableLocalUserAdministration() 296 { 297 return $this->field_changeable_lua; 298 } 299 public function enableRequired($a_required) 300 { 301 $this->field_required = $a_required; 302 } 303 public function enabledRequired() 304 { 305 return $this->field_required; 306 } 307 public function enableSearchable($a_searchable) 308 { 309 $this->field_searchable = $a_searchable; 310 } 311 public function enabledSearchable() 312 { 313 return $this->field_searchable; 314 } 315 public function enableExport($a_export) 316 { 317 $this->field_export = $a_export; 318 } 319 public function enabledExport() 320 { 321 return $this->field_export; 322 } 323 public function enableCourseExport($a_course_export) 324 { 325 $this->field_course_export = $a_course_export; 326 } 327 public function enabledCourseExport() 328 { 329 return $this->field_course_export; 330 } 331 public function enableGroupExport($a_group_export) 332 { 333 $this->field_group_export = $a_group_export; 334 } 335 public function enabledGroupExport() 336 { 337 return $this->field_group_export; 338 } 339 340 public function enableCertificate($a_c) 341 { 342 $this->field_certificate = $a_c; 343 } 344 public function enabledCertificate() 345 { 346 return $this->field_certificate; 347 } 348 349 public function enableVisibleRegistration($a_visible_registration) 350 { 351 $this->field_visible_registration = $a_visible_registration; 352 } 353 public function enabledVisibleRegistration() 354 { 355 return $this->field_visible_registration; 356 } 357 358 /** 359 * @param mixed[] $a_values 360 * @param bool $a_with 361 * @return array 362 */ 363 public function fieldValuesToSelectArray($a_values, $a_with_selection_info = true) 364 { 365 global $DIC; 366 367 $lng = $DIC->language(); 368 $values = []; 369 if ($a_with_selection_info) { 370 $values[''] = $lng->txt('please_select'); 371 } 372 foreach ($a_values as $value) { 373 $values[$value] = $value; 374 } 375 if (count($values) > (int) $a_with_selection_info) { 376 return $values; 377 } 378 return []; 379 } 380 381 public function validateValues() 382 { 383 $number = 0; 384 $unique = array(); 385 foreach ($this->getFieldValues() as $value) { 386 if (!strlen($value)) { 387 continue; 388 } 389 $number++; 390 $unique[$value] = $value; 391 } 392 393 if (!count($unique)) { 394 return UDF_NO_VALUES; 395 } 396 if ($number != count($unique)) { 397 return UDF_DUPLICATE_VALUES; 398 } 399 return 0; 400 } 401 402 public function nameExists($a_field_name) 403 { 404 global $DIC; 405 406 $ilDB = $DIC['ilDB']; 407 408 $query = "SELECT * FROM udf_definition " . 409 "WHERE field_name = " . $this->db->quote($a_field_name, 'text') . " "; 410 $res = $ilDB->query($query); 411 412 return (bool) $res->numRows(); 413 } 414 415 public function add() 416 { 417 global $DIC; 418 419 $ilDB = $DIC['ilDB']; 420 421 // Add definition entry 422 $next_id = $ilDB->nextId('udf_definition'); 423 424 $values = array( 425 'field_id' => array('integer',$next_id), 426 'field_name' => array('text',$this->getFieldName()), 427 'field_type' => array('integer', (int) $this->getFieldType()), 428 'field_values' => array('clob',serialize($this->getFieldValues())), 429 'visible' => array('integer', (int) $this->enabledVisible()), 430 'changeable' => array('integer', (int) $this->enabledChangeable()), 431 'required' => array('integer', (int) $this->enabledRequired()), 432 'searchable' => array('integer', (int) $this->enabledSearchable()), 433 'export' => array('integer', (int) $this->enabledExport()), 434 'course_export' => array('integer', (int) $this->enabledCourseExport()), 435 'registration_visible' => array('integer', (int) $this->enabledVisibleRegistration()), 436 'visible_lua' => array('integer', (int) $this->enabledVisibleLocalUserAdministration()), 437 'changeable_lua' => array('integer', (int) $this->enabledChangeableLocalUserAdministration()), 438 'group_export' => array('integer', (int) $this->enabledGroupExport()), 439 'certificate' => array('integer', (int) $this->enabledCertificate()), 440 ); 441 442 $ilDB->insert('udf_definition', $values); 443 444 // add table field in usr_defined_data 445 $field_id = $next_id; 446 447 448 $this->__read(); 449 450 return $field_id; 451 } 452 public function delete($a_id) 453 { 454 global $DIC; 455 456 $ilDB = $DIC['ilDB']; 457 458 // Delete definitions 459 $query = "DELETE FROM udf_definition " . 460 "WHERE field_id = " . $this->db->quote($a_id, 'integer') . " "; 461 $res = $ilDB->manipulate($query); 462 463 // Delete usr_data entries 464 // $ilDB->dropTableColumn('udf_data','f_'.$a_id); 465 include_once("./Services/User/classes/class.ilUserDefinedData.php"); 466 ilUserDefinedData::deleteEntriesOfField($a_id); 467 468 $this->__read(); 469 470 return true; 471 } 472 473 public function update($a_id) 474 { 475 global $DIC; 476 477 $ilDB = $DIC['ilDB']; 478 479 $values = array( 480 'field_name' => array('text',$this->getFieldName()), 481 'field_type' => array('integer', (int) $this->getFieldType()), 482 'field_values' => array('clob',serialize($this->getFieldValues())), 483 'visible' => array('integer', (int) $this->enabledVisible()), 484 'changeable' => array('integer', (int) $this->enabledChangeable()), 485 'required' => array('integer', (int) $this->enabledRequired()), 486 'searchable' => array('integer', (int) $this->enabledSearchable()), 487 'export' => array('integer', (int) $this->enabledExport()), 488 'course_export' => array('integer', (int) $this->enabledCourseExport()), 489 'registration_visible' => array('integer', (int) $this->enabledVisibleRegistration()), 490 'visible_lua' => array('integer', (int) $this->enabledVisibleLocalUserAdministration()), 491 'changeable_lua' => array('integer', (int) $this->enabledChangeableLocalUserAdministration()), 492 'group_export' => array('integer', (int) $this->enabledGroupExport()), 493 'certificate' => array('integer', (int) $this->enabledCertificate()) 494 ); 495 $ilDB->update('udf_definition', $values, array('field_id' => array('integer',$a_id))); 496 $this->__read(); 497 498 return true; 499 } 500 501 502 503 // Private 504 public function __read() 505 { 506 global $DIC; 507 508 $ilSetting = $DIC['ilSetting']; 509 510 $query = "SELECT * FROM udf_definition "; 511 $res = $this->db->query($query); 512 513 $this->definitions = array(); 514 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { 515 $this->definitions[$row->field_id]['field_id'] = $row->field_id; 516 $this->definitions[$row->field_id]['field_name'] = $row->field_name; 517 $this->definitions[$row->field_id]['field_type'] = $row->field_type; 518 $this->definitions[$row->field_id]['il_id'] = 'il_' . $ilSetting->get('inst_id', 0) . '_udf_' . $row->field_id; 519 520 // #16953 521 $tmp = $sort = array(); 522 $is_numeric = true; 523 foreach ((array) unserialize($row->field_values) as $item) { 524 if (!is_numeric($item)) { 525 $is_numeric = false; 526 } 527 $sort[] = array("value" => $item); 528 } 529 foreach (ilUtil::sortArray($sort, "value", "asc", $is_numeric) as $item) { 530 $tmp[] = $item["value"]; 531 } 532 533 $this->definitions[$row->field_id]['field_values'] = $tmp; 534 $this->definitions[$row->field_id]['visible'] = $row->visible; 535 $this->definitions[$row->field_id]['changeable'] = $row->changeable; 536 $this->definitions[$row->field_id]['required'] = $row->required; 537 $this->definitions[$row->field_id]['searchable'] = $row->searchable; 538 $this->definitions[$row->field_id]['export'] = $row->export; 539 $this->definitions[$row->field_id]['course_export'] = $row->course_export; 540 $this->definitions[$row->field_id]['visib_reg'] = $row->registration_visible; 541 $this->definitions[$row->field_id]['visib_lua'] = $row->visible_lua; 542 $this->definitions[$row->field_id]['changeable_lua'] = $row->changeable_lua; 543 $this->definitions[$row->field_id]['group_export'] = $row->group_export; 544 // fraunhpatch start 545 $this->definitions[$row->field_id]['certificate'] = $row->certificate; 546 // fraunhpatch end 547 } 548 549 return true; 550 } 551 552 553 public function deleteValue($a_field_id, $a_value_id) 554 { 555 global $DIC; 556 557 $ilDB = $DIC['ilDB']; 558 559 $definition = $this->getDefinition($a_field_id); 560 561 $counter = 0; 562 $new_values = array(); 563 foreach ($definition['field_values'] as $value) { 564 if ($counter++ != $a_value_id) { 565 $new_values[] = $value; 566 } else { 567 $old_value = $value; 568 } 569 } 570 571 $values = array( 572 'field_values' => array('clob',serialize($new_values))); 573 $ilDB->update('udf_definition', $values, array('field_id' => array('integer',$a_field_id))); 574 575 576 // sets value to '' where old value is $old_value 577 include_once("./Services/User/classes/class.ilUserDefinedData.php"); 578 ilUserDefinedData::deleteFieldValue($a_field_id, $old_value); 579 580 // fianally read data 581 $this->__read(); 582 583 return true; 584 } 585 586 public function toXML() 587 { 588 include_once './Services/Xml/classes/class.ilXmlWriter.php'; 589 $xml_writer = new ilXmlWriter(); 590 591 $this->addToXML($xml_writer); 592 593 return $xml_writer->xmlDumpMem(false); 594 } 595 596 /** 597 * add user defined field data to xml (using usr dtd) 598 * @param*XmlWriter $xml_writer 599 */ 600 public function addToXML($xml_writer) 601 { 602 $xml_writer->xmlStartTag("UDFDefinitions"); 603 foreach ($this->getDefinitions() as $definition) { 604 $attributes = array( 605 "Id" => $definition ["il_id"], 606 "Type" => $definition["field_type"] == UDF_TYPE_SELECT? "SELECT" : "TEXT", 607 "Visible" => $definition["visible"]? "TRUE" : "FALSE", 608 "Changeable" => $definition["changeable"]? "TRUE" : "FALSE", 609 "Required" => $definition["required"]? "TRUE" : "FALSE", 610 "Searchable" => $definition["searchable"]? "TRUE" : "FALSE", 611 "CourseExport" => $definition["course_export"]? "TRUE" : "FALSE", 612 "GroupExport" => $definition["group_export"]? "TRUE" : "FALSE", 613 "Certificate" => $definition["certificate"]? "TRUE" : "FALSE", 614 "Export" => $definition["export"]? "TRUE" : "FALSE", 615 "RegistrationVisible" => $definition["visib_reg"]? "TRUE" : "FALSE", 616 "LocalUserAdministrationVisible" => $definition["visib_lua"]? "TRUE" : "FALSE", 617 "LocalUserAdministrationChangeable" => $definition["changeable_lua"]? "TRUE" : "FALSE", 618 619 ); 620 $xml_writer->xmlStartTag("UDFDefinition", $attributes); 621 $xml_writer->xmlElement('UDFName', null, $definition['field_name']); 622 if ($definition["field_type"] == UDF_TYPE_SELECT) { 623 $field_values = $definition["field_values"]; 624 foreach ($field_values as $field_value) { 625 $xml_writer->xmlElement('UDFValue', null, $field_value); 626 } 627 } 628 $xml_writer->xmlEndTag("UDFDefinition"); 629 } 630 $xml_writer->xmlEndTag("UDFDefinitions"); 631 } 632 633 634 public static function _newInstance() 635 { 636 static $udf = null; 637 638 return $udf = new ilUserDefinedFields(); 639 } 640} 641