ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
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 
4 include_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  protected static $stored_record_map = [];
30  protected static $stored_fields_map = [];
31 
41  public function __construct($a_record_id, $a_obj_id, $a_sub_type = "-", $a_sub_id = 0)
42  {
43  $this->record_id = (int) $a_record_id;
44  $this->obj_id = (int) $a_obj_id;
45  $this->sub_type = $a_sub_type ? $a_sub_type : "-";
46  $this->sub_id = (int) $a_sub_id;
47  }
48 
56  public static function getInstancesForObjectId($a_obj_id, $a_obj_type = null, $a_sub_type = "-", $a_sub_id = 0)
57  {
58  $res = array();
59 
60  if (!$a_obj_type) {
61  $a_obj_type = ilObject::_lookupType($a_obj_id);
62  }
63 
64  // @todo refactor
65  $refs = ilObject::_getAllReferences($a_obj_id);
66  foreach ($refs as $ref_id) {
67  $records = ilAdvancedMDRecord::_getSelectedRecordsByObject($a_obj_type, $ref_id, $a_sub_type);
68  $orderings = new ilAdvancedMDRecordObjectOrderings();
69  $records = $orderings->sortRecords($records, $a_obj_id);
70 
71  foreach ($records as $record) {
72  $id = $record->getRecordId();
73 
74  if (!isset($res[$id])) {
75  $res[$id] = new self($id, $a_obj_id, $a_sub_type, $a_sub_id);
76  }
77  }
78  }
79  return $res;
80  }
81 
89  public function setActiveRecordPrimary($a_obj_id, $a_sub_type = "-", $a_sub_id = 0)
90  {
91  $this->obj_id = (int) $a_obj_id;
92  $this->sub_type = $a_sub_type ? $a_sub_type : "-";
93  $this->sub_id = (int) $a_sub_id;
94 
95  // make sure they get used
96  $this->active_record = null;
97  }
98 
104  public function getDefinitions()
105  {
106  if (!is_array($this->defs)) {
107  $this->defs = ilAdvancedMDFieldDefinition::getInstancesByRecordId($this->record_id);
108  }
109  return $this->defs;
110  }
111 
117  public function getADTGroup()
118  {
119  if (!$this->adt_group instanceof ilADTGroup) {
121  }
122  return $this->adt_group;
123  }
124 
130  protected function getActiveRecord()
131  {
132  if (!$this->active_record instanceof ilADTActiveRecordByType) {
133  include_once "Services/ADT/classes/class.ilADTFactory.php";
135 
136  $adt_group_db = $factory->getDBBridgeForInstance($this->getADTGroup());
137 
138  $primary = array(
139  "obj_id" => array("integer", $this->obj_id),
140  "sub_type" => array("text", $this->sub_type),
141  "sub_id" => array("integer", $this->sub_id)
142  );
143  $adt_group_db->setPrimary($primary);
144  $adt_group_db->setTable("adv_md_values");
145 
146  // multi-enum fakes single in adv md
147  foreach ($adt_group_db->getElements() as $element) {
148  if ($element->getADT()->getType() == "MultiEnum") {
149  $element->setFakeSingle(true);
150  }
151  }
152 
153  $this->active_record = $factory->getActiveRecordByTypeInstance($adt_group_db);
154  $this->active_record->setElementIdColumn("field_id", "integer");
155  }
156 
157  return $this->active_record;
158  }
159 
166  public static function findByObjectId($a_obj_id)
167  {
168  include_once "Services/ADT/classes/class.ilADTFactory.php";
170  return ilADTActiveRecordByType::readByPrimary("adv_md_values", array("obj_id" => array("integer", $a_obj_id)));
171  }
172 
173 
174  //
175  // disabled
176  //
177 
178  // to set disabled use self::write() with additional data
179 
186  public function isDisabled($a_element_id)
187  {
188  if (is_array($this->disabled)) {
189  return in_array($a_element_id, $this->disabled);
190  }
191  }
192 
193 
194  //
195  // CRUD
196  //
197 
201  public function read()
202  {
203  $this->disabled = array();
204 
205  $tmp = $this->getActiveRecord()->read(true);
206  if ($tmp) {
207  foreach ($tmp as $element_id => $data) {
208  if ($data["disabled"]) {
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  }
241 
247  public static function _deleteByObjId($a_obj_id)
248  {
249  ilADTFactory::getInstance()->initActiveRecordByType();
251  "adv_md_values",
252  array("obj_id" => array("integer", $a_obj_id))
253  );
254  }
255 
256 
257 
258  //
259  // substitutions (aka list gui)
260  //
261 
267  public static function preloadByObjIds(array $a_obj_ids)
268  {
269  global $DIC;
270 
271  $ilDB = $DIC['ilDB'];
272 
273  // preload values
274  ilADTFactory::getInstance()->initActiveRecordByType();
276  "adv_md_values",
277  array("obj_id" => array("integer", $a_obj_ids))
278  );
279 
280 
281  // preload record ids for object types
282 
283  self::$preload_obj_records = array();
284 
285  // get active records for object types
286  $query = "SELECT amro.*" .
287  " FROM adv_md_record_objs amro" .
288  " JOIN adv_md_record amr ON (amr.record_id = amro.record_id)" .
289  " WHERE active = " . $ilDB->quote(1, "integer");
290  $set = $ilDB->query($query);
291  while ($row = $ilDB->fetchAssoc($set)) {
292  self::$preload_obj_records[$row["obj_type"]][] = array($row["record_id"], $row["optional"]);
293  }
294  }
295 
296  public static function preloadedRead($a_type, $a_obj_id)
297  {
298  $res = array();
299 
300  if (isset(self::$preload_obj_records[$a_type])) {
301  foreach (self::$preload_obj_records[$a_type] as $item) {
302  $record_id = $item[0];
303 
304  // record is optional, check activation for object
305  if ($item[1]) {
306  $found = false;
307  include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php";
308  foreach (ilAdvancedMDRecord::_getSelectedRecordsByObject($a_type, $a_obj_id) as $record) {
309  if ($record->getRecordId() == $item[0]) {
310  $found = true;
311  }
312  }
313  if (!$found) {
314  continue;
315  }
316  }
317 
318  $res[$record_id] = new self($record_id, $a_obj_id);
319  $res[$record_id]->read();
320  }
321  }
322 
323  return $res;
324  }
325 
326 
327  //
328  // copy/export (import: ilAdvancedMDValueParser)
329  //
330 
340  public static function _cloneValues($a_source_id, $a_target_id, $a_sub_type = null, $a_source_sub_id = null, $a_target_sub_id = null, $use_stored_record_map = false)
341  {
342  global $DIC;
343 
344  $ilLog = $DIC['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  if ($record->getParentObject() == $a_source_id && !$use_stored_record_map) {
354  $tmp = array();
355  if ($a_source_id != $a_target_id) {
356  $new_records[$record->getRecordId()] = $record->_clone($tmp, $a_target_id);
357  } else {
358  $new_records[$record->getRecordId()] = $record->getRecordId();
359  }
360  $fields_map[$record->getRecordId()] = $tmp;
361  }
362  }
363  if (!$use_stored_record_map) {
364  self::$stored_record_map = $new_records;
365  self::$stored_fields_map = $fields_map;
366  } else {
367  $new_records = self::$stored_record_map;
368  $fields_map = self::$stored_fields_map;
369  }
370 
371 
372  // object record selection
373 
374  $source_sel = ilAdvancedMDRecord::getObjRecSelection($a_source_id, $a_sub_type);
375  if ($source_sel) {
376  $target_sel = array();
377  foreach ($source_sel as $record_id) {
378  // (local) record has been cloned
379  if (array_key_exists($record_id, $new_records)) {
380  $record_id = $new_records[$record_id]->getRecordId();
381  }
382  $target_sel[] = $record_id;
383  }
384  ilAdvancedMDRecord::saveObjRecSelection($a_target_id, $a_sub_type, $target_sel);
385  }
386 
387  // clone values
388 
389  $source_primary = array("obj_id" => array("integer", $a_source_id));
390  $target_primary = array("obj_id" => array("integer", $a_target_id));
391 
392  // sub-type support
393  if ($a_sub_type &&
394  $a_source_sub_id &&
395  $a_target_sub_id) {
396  $source_primary["sub_type"] = array("text", $a_sub_type);
397  $source_primary["sub_id"] = array("integer", $a_source_sub_id);
398  $target_primary["sub_type"] = array("text", $a_sub_type);
399  $target_primary["sub_id"] = array("integer", $a_target_sub_id);
400  }
401 
402  ilADTFactory::getInstance()->initActiveRecordByType();
404  "adv_md_values",
405  array(
406  "obj_id" => "integer",
407  "sub_type" => "text",
408  "sub_id" => "integer",
409  "field_id" => "integer"
410  ),
411  $source_primary,
412  $target_primary,
413  array("disabled" => "integer")
414  );
415 
416 
417  // move values of local records to newly created fields
418 
419  foreach ($fields_map as $source_record_id => $fields) {
420  // just to make sure
421  if (array_key_exists($source_record_id, $new_records)) {
422  foreach ($fields as $source_field_id => $target_field_id) {
423  // delete entry for old field id (was cloned above)
424  $del_target_primary = $target_primary;
425  $del_target_primary["field_id"] = array("integer", $source_field_id);
426  ilADTActiveRecordByType::deleteByPrimary("adv_md_values", $del_target_primary);
427 
428  // create entry for new id
429  $fix_source_primary = $source_primary;
430  $fix_source_primary["field_id"] = array("integer", $source_field_id);
431  $fix_target_primary = $target_primary;
432  $fix_target_primary["field_id"] = array("integer", $target_field_id);
434  "adv_md_values",
435  array(
436  "obj_id" => "integer",
437  "sub_type" => "text",
438  "sub_id" => "integer",
439  "field_id" => "integer"
440  ),
441  $fix_source_primary,
442  $fix_target_primary,
443  array("disabled" => "integer")
444  );
445  }
446  }
447  }
448 
449  if (!$has_cloned) {
450  $ilLog->write(__METHOD__ . ': No advanced meta data found.');
451  } else {
452  $ilLog->write(__METHOD__ . ': Start cloning advanced meta data.');
453  }
454  return true;
455  }
456 
463  public static function _appendXMLByObjId(ilXmlWriter $a_xml_writer, $a_obj_id)
464  {
465  $a_xml_writer->xmlStartTag('AdvancedMetaData');
466 
467  self::preloadByObjIds(array($a_obj_id));
468  $values_records = self::preloadedRead(ilObject::_lookupType($a_obj_id), $a_obj_id);
469 
470  foreach ($values_records as $values_record) {
471  $defs = $values_record->getDefinitions();
472  foreach ($values_record->getADTGroup()->getElements() as $element_id => $element) {
473  $def = $defs[$element_id];
474 
475  $value = null;
476  if (!$element->isNull()) {
477  $value = $def->getValueForXML($element);
478  }
479 
480  $a_xml_writer->xmlElement(
481  'Value',
482  array('id' => $def->getImportId()),
483  $value
484  );
485  }
486  }
487 
488  $a_xml_writer->xmlEndTag('AdvancedMetaData');
489  }
490 
491 
492  //
493  // glossary (might be generic)
494  //
495 
502  public static function queryForRecords($adv_rec_obj_ref_id, $adv_rec_obj_type, $adv_rec_obj_subtype, $a_obj_id, $a_subtype, $a_records, $a_obj_id_key, $a_obj_subid_key, array $a_amet_filter = null)
503  {
504  $results = array();
505 
506  if (!is_array($a_obj_id)) {
507  $a_obj_id = array($a_obj_id);
508  }
509 
510  $sub_obj_ids = array();
511  foreach ($a_records as $rec) {
512  $sub_obj_ids[] = $rec[$a_obj_subid_key];
513  }
514 
515  // preload adv data for object id(s)
516  ilADTFactory::getInstance()->initActiveRecordByType();
518  "adv_md_values",
519  array(
520  "obj_id" => array("integer", $a_obj_id),
521  "sub_type" => array("text", $a_subtype),
522  "sub_id" => array("integer", $sub_obj_ids)
523  )
524  );
525 
526  $record_groups = array();
527 
528  foreach ($a_records as $rec) {
529  $obj_id = (int) $rec[$a_obj_id_key];
530  $sub_id = $rec[$a_obj_subid_key];
531 
532  // get adv records
533  foreach (ilAdvancedMDRecord::_getSelectedRecordsByObject($adv_rec_obj_type, $adv_rec_obj_ref_id, $adv_rec_obj_subtype) as $adv_record) {
534  $record_id = $adv_record->getRecordId();
535 
536  if (!isset($record_groups[$record_id])) {
539  $record_groups[$record_id] = ilADTFactory::getInstance()->getDBBridgeForInstance($record_groups[$record_id]);
540  $record_groups[$record_id]->setTable("adv_md_values");
541  }
542 
543  // prepare ADT group for record id
544  $record_groups[$record_id]->setPrimary(array(
545  "obj_id" => array("integer", $obj_id),
546  "sub_type" => array("text", $a_subtype),
547  "sub_id" => array("integer", $sub_id)
548  ));
549  // multi-enum fakes single in adv md
550  foreach ($record_groups[$record_id]->getElements() as $element) {
551  if ($element->getADT()->getType() == "MultiEnum") {
552  $element->setFakeSingle(true);
553  }
554  }
555 
556  // read (preloaded) data
557  $active_record = new ilADTActiveRecordByType($record_groups[$record_id]);
558  $active_record->setElementIdColumn("field_id", "integer");
559  $active_record->read();
560 
561  $adt_group = $record_groups[$record_id]->getADT();
562 
563  // filter against amet values
564  if ($a_amet_filter) {
565  foreach ($a_amet_filter as $field_id => $element) {
566  if ($adt_group->hasElement($field_id)) {
567  if (!$element->isInCondition($adt_group->getElement($field_id))) {
568  continue(3);
569  }
570  }
571  }
572  }
573  // add amet values to glossary term record
574  foreach ($adt_group->getElements() as $element_id => $element) {
575  if (!$element->isNull()) {
576  // we are reusing the ADT group for all $a_records, so we need to clone
577  $pb = ilADTFactory::getInstance()->getPresentationBridgeForInstance(clone $element);
578  $rec["md_" . $element_id] = $pb->getSortable();
579  $rec["md_" . $element_id . "_presentation"] = $pb;
580  } else {
581  $rec["md_" . $element_id] = null;
582  }
583  }
584  }
585 
586  $results[] = $rec;
587  }
588 
589  return $results;
590  }
591 }
getType()
Get type (from class/instance)
Definition: class.ilADT.php:53
static getInstancesForObjectId($a_obj_id, $a_obj_type=null, $a_sub_type="-", $a_sub_id=0)
Get instances for given object id.
xmlStartTag($tag, $attrs=null, $empty=false, $encode=true, $escape=true)
Writes a starttag.
$data
Definition: storeScorm.php:23
ADT Active Record by type helper class.
static _getRecords()
Get records.
static initActiveRecordByType()
Init active record by type.
static preloadByObjIds(array $a_obj_ids)
Preload list gui data.
static getADTGroupForDefinitions(array $a_defs)
Init ADTGroup for definitions.
XML writer class.
static _appendXMLByObjId(ilXmlWriter $a_xml_writer, $a_obj_id)
Get xml of object values.
static _deleteByFieldId($a_field_id, ilADT $a_adt)
Delete values by field_id.
static getInstance()
Get singleton.
static preloadByPrimary($a_table, array $a_primary)
Read values by (partial) primary key.
ADT base class.
Definition: class.ilADT.php:11
static saveObjRecSelection($a_obj_id, $a_sub_type="", array $a_records=null, $a_delete_before=true)
Save repository object record selection.
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 _getAllReferences($a_id)
get all reference ids of object
xmlEndTag($tag)
Writes an endtag.
static _deleteByObjId($a_obj_id)
Delete by objekt id.
static _getSelectedRecordsByObject($a_obj_type, $a_ref_id, $a_sub_type="")
Get selected records by object.
setActiveRecordPrimary($a_obj_id, $a_sub_type="-", $a_sub_id=0)
Set the primary values for active record.
static findByObjectId($a_obj_id)
Find all entries for object (regardless of sub-type/sub-id)
foreach($_POST as $key=> $value) $res
getActiveRecord()
Init ADT DB Bridge (aka active record helper class)
static deleteByPrimary($a_table, array $a_primary, $a_type=null)
Delete values by (partial) primary key.
__construct($a_record_id, $a_obj_id, $a_sub_type="-", $a_sub_id=0)
Constructor.
static readByPrimary($a_table, array $a_primary, $a_type=null)
Read directly.
global $DIC
Definition: goto.php:24
getADTGroup()
Init ADT group for current record.
disabled()
Example showing how to plug a disabled checkbox into a form.
Definition: disabled.php:5
$query
$results
static _lookupType($a_id, $a_reference=false)
lookup object type
xmlElement($tag, $attrs=null, $data=null, $encode=true, $escape=true)
Writes a basic element (no children, just textual content)
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, $use_stored_record_map=false)
Clone Advanced Meta Data.
write(array $a_additional_data=null)
Write record values.
read()
Get record values.
global $ilDB
static preloadedRead($a_type, $a_obj_id)
static getInstancesByRecordId($a_record_id, $a_only_searchable=false, string $language='')
Get definitions by record id.
static getObjRecSelection($a_obj_id, $a_sub_type="")
Get repository object record selection.
$factory
Definition: metadata.php:58
static queryForRecords($adv_rec_obj_ref_id, $adv_rec_obj_type, $adv_rec_obj_subtype, $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.
getDefinitions()
Get record field definitions.