ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilAdvancedMDValues.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDFieldDefinition.php";
5
16{
17 protected $record_id; // [int]
18 protected $obj_id; // [int]
19 protected $sub_id; // [int]
20 protected $sub_type; // [int]
21
22 protected $defs; // [array]
23 protected $adt_group; // [ilADTGroup]
24 protected $active_record; // [ilADTActiveRecordByType]
25
26 protected $disabled; // [array]
27
28 protected static $preload_obj_records; // [array]
29
39 public function __construct($a_record_id, $a_obj_id, $a_sub_type = "-", $a_sub_id = 0)
40 {
41 $this->record_id = (int)$a_record_id;
42 $this->obj_id = (int)$a_obj_id;
43 $this->sub_type = $a_sub_type ? $a_sub_type : "-";
44 $this->sub_id = (int)$a_sub_id;
45 }
46
54 public static function getInstancesForObjectId($a_obj_id, $a_obj_type = null, $a_sub_type = "-", $a_sub_id = 0)
55 {
56 $res = array();
57
58 if(!$a_obj_type)
59 {
60 $a_obj_type = ilObject::_lookupType($a_obj_id);
61 }
62
63 include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php";
64 foreach(ilAdvancedMDRecord::_getSelectedRecordsByObject($a_obj_type, $a_obj_id, $a_sub_type) as $record)
65 {
66 $id = $record->getRecordId();
67 $res[$id] = new self($id, $a_obj_id, $a_sub_type, $a_sub_id);
68 }
69
70 return $res;
71 }
72
80 public function setActiveRecordPrimary($a_obj_id, $a_sub_type = "-", $a_sub_id = 0)
81 {
82 $this->obj_id = (int)$a_obj_id;
83 $this->sub_type = $a_sub_type ? $a_sub_type : "-";
84 $this->sub_id = (int)$a_sub_id;
85
86 // make sure they get used
87 $this->active_record = null;
88 }
89
95 public function getDefinitions()
96 {
97 if(!is_array($this->defs))
98 {
99 $this->defs = ilAdvancedMDFieldDefinition::getInstancesByRecordId($this->record_id);
100 }
101 return $this->defs;
102 }
103
109 public function getADTGroup()
110 {
111 if(!$this->adt_group instanceof ilADTGroup)
112 {
114 }
115 return $this->adt_group;
116 }
117
123 protected function getActiveRecord()
124 {
125 if(!$this->active_record instanceof ilADTActiveRecordByType)
126 {
127 include_once "Services/ADT/classes/class.ilADTFactory.php";
128 $factory = ilADTFactory::getInstance();
129
130 $adt_group_db = $factory->getDBBridgeForInstance($this->getADTGroup());
131
132 $primary = array(
133 "obj_id" => array("integer", $this->obj_id),
134 "sub_type" => array("text", $this->sub_type),
135 "sub_id" => array("integer", $this->sub_id)
136 );
137 $adt_group_db->setPrimary($primary);
138 $adt_group_db->setTable("adv_md_values");
139
140 // multi-enum fakes single in adv md
141 foreach($adt_group_db->getElements() as $element)
142 {
143 if($element->getADT()->getType() == "MultiEnum")
144 {
145 $element->setFakeSingle(true);
146 }
147 }
148
149 $this->active_record = $factory->getActiveRecordByTypeInstance($adt_group_db);
150 $this->active_record->setElementIdColumn("field_id", "integer");
151 }
152
154 }
155
162 public static function findByObjectId($a_obj_id)
163 {
164 include_once "Services/ADT/classes/class.ilADTFactory.php";
166 return ilADTActiveRecordByType::readByPrimary("adv_md_values", array("obj_id"=>array("integer", $a_obj_id)));
167 }
168
169
170 //
171 // disabled
172 //
173
174 // to set disabled use self::write() with additional data
175
182 public function isDisabled($a_element_id)
183 {
184 if(is_array($this->disabled))
185 {
186 return in_array($a_element_id, $this->disabled);
187 }
188 }
189
190
191 //
192 // CRUD
193 //
194
198 public function read()
199 {
200 $this->disabled = array();
201
202 $tmp = $this->getActiveRecord()->read(true);
203 if($tmp)
204 {
205 foreach($tmp as $element_id => $data)
206 {
207 if($data["disabled"])
208 {
209 $this->disabled[] = $element_id;
210 }
211 }
212 }
213 }
214
220 public function write(array $a_additional_data = null)
221 {
222 $this->getActiveRecord()->write($a_additional_data);
223 }
224
232 public static function _deleteByFieldId($a_field_id, ilADT $a_adt)
233 {
234 ilADTFactory::getInstance()->initActiveRecordByType();
236 "adv_md_values",
237 array("field_id"=>array("integer", $a_field_id)),
238 $a_adt->getType());
239 }
240
246 public static function _deleteByObjId($a_obj_id)
247 {
248 ilADTFactory::getInstance()->initActiveRecordByType();
250 "adv_md_values",
251 array("obj_id"=>array("integer", $a_obj_id)));
252 }
253
254
255
256 //
257 // substitutions (aka list gui)
258 //
259
265 public static function preloadByObjIds(array $a_obj_ids)
266 {
267 global $ilDB;
268
269 // preload values
270 ilADTFactory::getInstance()->initActiveRecordByType();
272 "adv_md_values",
273 array("obj_id"=>array("integer", $a_obj_ids)));
274
275
276 // preload record ids for object types
277
278 self::$preload_obj_records = array();
279
280 // get active records for object types
281 $query = "SELECT amro.*".
282 " FROM adv_md_record_objs amro".
283 " JOIN adv_md_record amr ON (amr.record_id = amro.record_id)".
284 " WHERE active = ".$ilDB->quote(1, "integer");
285 $set = $ilDB->query($query);
286 while($row = $ilDB->fetchAssoc($set))
287 {
288 self::$preload_obj_records[$row["obj_type"]][] = array($row["record_id"], $row["optional"]);
289 }
290 }
291
292 public static function preloadedRead($a_type, $a_obj_id)
293 {
294 $res = array();
295
296 if(isset(self::$preload_obj_records[$a_type]))
297 {
298 foreach(self::$preload_obj_records[$a_type] as $item)
299 {
300 $record_id = $item[0];
301
302 // record is optional, check activation for object
303 if($item[1])
304 {
305 $found = false;
306 include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php";
307 foreach(ilAdvancedMDRecord::_getSelectedRecordsByObject($a_type, $a_obj_id) as $record)
308 {
309 if($record->getRecordId() == $item[0])
310 {
311 $found = true;
312 }
313 }
314 if(!$found)
315 {
316 continue;
317 }
318 }
319
320 $res[$record_id] = new self($record_id, $a_obj_id);
321 $res[$record_id]->read();
322 }
323 }
324
325 return $res;
326 }
327
328
329 //
330 // copy/export (import: ilAdvancedMDValueParser)
331 //
332
342 public static function _cloneValues($a_source_id,$a_target_id,$a_sub_type = null,$a_source_sub_id = null,$a_target_sub_id=null)
343 {
344 global $ilLog;
345
346 // clone local records
347
348 // new records are created automatically, only if source and target id differs.
349 include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php";
350 $new_records = $fields_map = array();
351
352 foreach(ilAdvancedMDRecord::_getRecords() as $record)
353 {
354 if($record->getParentObject() == $a_source_id)
355 {
356 $tmp = array();
357 if($a_source_id != $a_target_id)
358 {
359 $new_records[$record->getRecordId()] = $record->_clone($tmp, $a_target_id);
360 }
361 else
362 {
363 $new_records[$record->getRecordId()] = $record->getRecordId();
364 }
365 $fields_map[$record->getRecordId()] = $tmp;
366 }
367 }
368
369
370 // object record selection
371
372 $source_sel = ilAdvancedMDRecord::getObjRecSelection($a_source_id, $a_sub_type);
373 if($source_sel)
374 {
375 $target_sel = array();
376 foreach($source_sel as $record_id)
377 {
378 // (local) record has been cloned
379 if(array_key_exists($record_id, $new_records))
380 {
381 $record_id = $new_records[$record_id]->getRecordId();
382 }
383 $target_sel[] = $record_id;
384 }
385 ilAdvancedMDRecord::saveObjRecSelection($a_target_id, $a_sub_type, $target_sel);
386 }
387
388 // clone values
389
390 $source_primary = array("obj_id"=>array("integer", $a_source_id));
391 $target_primary = array("obj_id"=>array("integer", $a_target_id));
392
393 // sub-type support
394 if($a_sub_type &&
395 $a_source_sub_id &&
396 $a_target_sub_id)
397 {
398 $source_primary["sub_type"] = array("text", $a_sub_type);
399 $source_primary["sub_id"] = array("integer", $a_source_sub_id);
400 $target_primary["sub_type"] = array("text", $a_sub_type);
401 $target_primary["sub_id"] = array("integer", $a_target_sub_id);
402 }
403
404 ilADTFactory::getInstance()->initActiveRecordByType();
406 "adv_md_values",
407 array(
408 "obj_id" => "integer",
409 "sub_type" => "text",
410 "sub_id" => "integer",
411 "field_id" => "integer"
412 ),
413 $source_primary,
414 $target_primary,
415 array("disabled"=>"integer"));
416
417
418 // move values of local records to newly created fields
419
420 foreach($fields_map as $source_record_id => $fields)
421 {
422 // just to make sure
423 if(array_key_exists($source_record_id, $new_records))
424 {
425 foreach($fields as $source_field_id => $target_field_id)
426 {
427 // delete entry for old field id (was cloned above)
428 $del_target_primary = $target_primary;
429 $del_target_primary["field_id"] = array("integer", $source_field_id);
430 ilADTActiveRecordByType::deleteByPrimary("adv_md_values", $del_target_primary);
431
432 // create entry for new id
433 $fix_source_primary = $source_primary;
434 $fix_source_primary["field_id"] = array("integer", $source_field_id);
435 $fix_target_primary = $target_primary;
436 $fix_target_primary["field_id"] = array("integer", $target_field_id);
438 "adv_md_values",
439 array(
440 "obj_id" => "integer",
441 "sub_type" => "text",
442 "sub_id" => "integer",
443 "field_id" => "integer"
444 ),
445 $fix_source_primary,
446 $fix_target_primary,
447 array("disabled"=>"integer"));
448 }
449 }
450 }
451
452 if(!$has_cloned)
453 {
454 $ilLog->write(__METHOD__.': No advanced meta data found.');
455 }
456 else
457 {
458 $ilLog->write(__METHOD__.': Start cloning advanced meta data.');
459 }
460 return true;
461 }
462
469 public static function _appendXMLByObjId(ilXmlWriter $a_xml_writer, $a_obj_id)
470 {
471 $a_xml_writer->xmlStartTag('AdvancedMetaData');
472
473 self::preloadByObjIds(array($a_obj_id));
474 $values_records = self::preloadedRead(ilObject::_lookupType($a_obj_id), $a_obj_id);
475
476 foreach($values_records as $values_record)
477 {
478 $defs = $values_record->getDefinitions();
479 foreach($values_record->getADTGroup()->getElements() as $element_id => $element)
480 {
481 $def = $defs[$element_id];
482
483 $value = null;
484 if(!$element->isNull())
485 {
486 $value = $def->getValueForXML($element);
487 }
488
489 $a_xml_writer->xmlElement(
490 'Value',
491 array('id' => $def->getImportId()),
492 $value
493 );
494 }
495 }
496
497 $a_xml_writer->xmlEndTag('AdvancedMetaData');
498 }
499
500
501 //
502 // glossary (might be generic)
503 //
504
511 static public function queryForRecords($a_obj_id, $a_subtype, $a_records, $a_obj_id_key, $a_obj_subid_key, array $a_amet_filter = null)
512 {
513 $results = array();
514
515 if (!is_array($a_obj_id))
516 {
517 $a_obj_id = array($a_obj_id);
518 }
519
520 $sub_obj_ids = array();
521 foreach($a_records as $rec)
522 {
523 $sub_obj_ids[] = $rec[$a_obj_subid_key];
524 }
525
526 // preload adv data for object id(s)
527 ilADTFactory::getInstance()->initActiveRecordByType();
529 array(
530 "obj_id" => array("integer", $a_obj_id),
531 "sub_type" => array("text", $a_subtype),
532 "sub_id" => array("integer", $sub_obj_ids)
533 ));
534
535 $record_groups = array();
536
537 foreach($a_records as $rec)
538 {
539 $obj_id = $rec[$a_obj_id_key];
540 $sub_id = $rec[$a_obj_subid_key];
541
542 // only active amet records for glossary
544 {
545 $record_id = $adv_record->getRecordId();
546
547 if(!isset($record_groups[$record_id]))
548 {
551 $record_groups[$record_id] = ilADTFactory::getInstance()->getDBBridgeForInstance($record_groups[$record_id]);
552 $record_groups[$record_id]->setTable("adv_md_values");
553 }
554
555 // prepare ADT group for record id
556 $record_groups[$record_id]->setPrimary(array(
557 "obj_id" => array("integer", $obj_id),
558 "sub_type" => array("text", $a_subtype),
559 "sub_id" => array("integer", $sub_id)
560 ));
561
562 // multi-enum fakes single in adv md
563 foreach($record_groups[$record_id]->getElements() as $element)
564 {
565 if($element->getADT()->getType() == "MultiEnum")
566 {
567 $element->setFakeSingle(true);
568 }
569 }
570
571 // read (preloaded) data
572 $active_record = new ilADTActiveRecordByType($record_groups[$record_id]);
573 $active_record->setElementIdColumn("field_id", "integer");
574 $active_record->read();
575
576 $adt_group = $record_groups[$record_id]->getADT();
577
578 // filter against amet values
579 if($a_amet_filter)
580 {
581 foreach($a_amet_filter as $field_id => $element)
582 {
583 if($adt_group->hasElement($field_id))
584 {
585 if(!$element->isInCondition($adt_group->getElement($field_id)))
586 {
587 continue(3);
588 }
589 }
590 }
591 }
592
593 // add amet values to glossary term record
594 foreach($adt_group->getElements() as $element_id => $element)
595 {
596 if(!$element->isNull())
597 {
598 // we are reusing the ADT group for all $a_records, so we need to clone
599 $pb = ilADTFactory::getInstance()->getPresentationBridgeForInstance(clone $element);
600 $rec["md_".$element_id] = $pb->getSortable();
601 $rec["md_".$element_id."_presentation"] = $pb;
602
603 }
604 else
605 {
606 $rec["md_".$element_id] = null;
607 }
608 }
609 }
610
611 $results[] = $rec;
612 }
613
614 return $results;
615 }
616}
617
618?>
An exception for terminatinating execution or to throw for unit testing.
ADT Active Record by type helper class.
static preloadByPrimary($a_table, array $a_primary)
Read values by (partial) primary key.
static deleteByPrimary($a_table, array $a_primary, $a_type=null)
Delete values by (partial) primary key.
static readByPrimary($a_table, array $a_primary, $a_type=null)
Read directly.
static cloneByPrimary($a_table, array $a_primary_def, array $a_source_primary, array $a_target_primary, array $a_additional=null)
Clone values by (partial) primary key.
static getInstance()
Get singleton.
static initActiveRecordByType()
Init active record by type.
ADT base class.
Definition: class.ilADT.php:12
getType()
Get type (from class/instance)
Definition: class.ilADT.php:51
static getADTGroupForDefinitions(array $a_defs)
Init ADTGroup for definitions.
static getInstancesByRecordId($a_record_id, $a_only_searchable=false)
Get definitions by record id.
static _getSelectedRecordsByObject($a_obj_type, $a_obj_id, $a_sub_type="")
Get selected records by object.
static saveObjRecSelection($a_obj_id, $a_sub_type="", array $a_records=null, $a_delete_before=true)
Save repository object record selection.
static getObjRecSelection($a_obj_id, $a_sub_type="")
Get repository object record selection.
static _getRecords()
Get records.
static _deleteByObjId($a_obj_id)
Delete by objekt id.
static queryForRecords($a_obj_id, $a_subtype, $a_records, $a_obj_id_key, $a_obj_subid_key, array $a_amet_filter=null)
Query data for given object records.
static getInstancesForObjectId($a_obj_id, $a_obj_type=null, $a_sub_type="-", $a_sub_id=0)
Get instances for given object id.
__construct($a_record_id, $a_obj_id, $a_sub_type="-", $a_sub_id=0)
Constructor.
static preloadByObjIds(array $a_obj_ids)
Preload list gui data.
static preloadedRead($a_type, $a_obj_id)
static findByObjectId($a_obj_id)
Find all entries for object (regardless of sub-type/sub-id)
isDisabled($a_element_id)
Is element disabled?
static _cloneValues($a_source_id, $a_target_id, $a_sub_type=null, $a_source_sub_id=null, $a_target_sub_id=null)
Clone Advanced Meta Data.
getDefinitions()
Get record field definitions.
setActiveRecordPrimary($a_obj_id, $a_sub_type="-", $a_sub_id=0)
Set the primary values for active record.
static _appendXMLByObjId(ilXmlWriter $a_xml_writer, $a_obj_id)
Get xml of object values.
getADTGroup()
Init ADT group for current record.
write(array $a_additional_data=null)
Write record values.
getActiveRecord()
Init ADT DB Bridge (aka active record helper class)
static _deleteByFieldId($a_field_id, ilADT $a_adt)
Delete values by field_id.
static _lookupType($a_id, $a_reference=false)
lookup object type
XML writer class.
xmlEndTag($tag)
Writes an endtag.
xmlStartTag($tag, $attrs=NULL, $empty=FALSE, $encode=TRUE, $escape=TRUE)
Writes a starttag.
xmlElement($tag, $attrs=NULL, $data=Null, $encode=TRUE, $escape=TRUE)
Writes a basic element (no children, just textual content)
$results
global $ilDB
$a_type
Definition: workflow.php:93