ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 
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  $a_obj_type = ilObject::_lookupType($a_obj_id);
60  }
61 
62  // @todo refactor
63  $refs = ilObject::_getAllReferences($a_obj_id);
64  foreach ($refs as $ref_id) {
65  $records = ilAdvancedMDRecord::_getSelectedRecordsByObject($a_obj_type, $ref_id, $a_sub_type);
66  $orderings = new ilAdvancedMDRecordObjectOrderings();
67  $records = $orderings->sortRecords($records, $a_obj_id);
68 
69  foreach ($records as $record) {
70  $id = $record->getRecordId();
71 
72  if (!isset($res[$id])) {
73  $res[$id] = new self($id, $a_obj_id, $a_sub_type, $a_sub_id);
74  }
75  }
76  }
77  return $res;
78  }
79 
87  public function setActiveRecordPrimary($a_obj_id, $a_sub_type = "-", $a_sub_id = 0)
88  {
89  $this->obj_id = (int) $a_obj_id;
90  $this->sub_type = $a_sub_type ? $a_sub_type : "-";
91  $this->sub_id = (int) $a_sub_id;
92 
93  // make sure they get used
94  $this->active_record = null;
95  }
96 
102  public function getDefinitions()
103  {
104  if (!is_array($this->defs)) {
105  $this->defs = ilAdvancedMDFieldDefinition::getInstancesByRecordId($this->record_id);
106  }
107  return $this->defs;
108  }
109 
115  public function getADTGroup()
116  {
117  if (!$this->adt_group instanceof ilADTGroup) {
119  }
120  return $this->adt_group;
121  }
122 
128  protected function getActiveRecord()
129  {
130  if (!$this->active_record instanceof ilADTActiveRecordByType) {
131  include_once "Services/ADT/classes/class.ilADTFactory.php";
133 
134  $adt_group_db = $factory->getDBBridgeForInstance($this->getADTGroup());
135 
136  $primary = array(
137  "obj_id" => array("integer", $this->obj_id),
138  "sub_type" => array("text", $this->sub_type),
139  "sub_id" => array("integer", $this->sub_id)
140  );
141  $adt_group_db->setPrimary($primary);
142  $adt_group_db->setTable("adv_md_values");
143 
144  // multi-enum fakes single in adv md
145  foreach ($adt_group_db->getElements() as $element) {
146  if ($element->getADT()->getType() == "MultiEnum") {
147  $element->setFakeSingle(true);
148  }
149  }
150 
151  $this->active_record = $factory->getActiveRecordByTypeInstance($adt_group_db);
152  $this->active_record->setElementIdColumn("field_id", "integer");
153  }
154 
155  return $this->active_record;
156  }
157 
164  public static function findByObjectId($a_obj_id)
165  {
166  include_once "Services/ADT/classes/class.ilADTFactory.php";
168  return ilADTActiveRecordByType::readByPrimary("adv_md_values", array("obj_id" => array("integer", $a_obj_id)));
169  }
170 
171 
172  //
173  // disabled
174  //
175 
176  // to set disabled use self::write() with additional data
177 
184  public function isDisabled($a_element_id)
185  {
186  if (is_array($this->disabled)) {
187  return in_array($a_element_id, $this->disabled);
188  }
189  }
190 
191 
192  //
193  // CRUD
194  //
195 
199  public function read()
200  {
201  $this->disabled = array();
202 
203  $tmp = $this->getActiveRecord()->read(true);
204  if ($tmp) {
205  foreach ($tmp as $element_id => $data) {
206  if ($data["disabled"]) {
207  $this->disabled[] = $element_id;
208  }
209  }
210  }
211  }
212 
218  public function write(array $a_additional_data = null)
219  {
220  $this->getActiveRecord()->write($a_additional_data);
221  }
222 
230  public static function _deleteByFieldId($a_field_id, ilADT $a_adt)
231  {
232  ilADTFactory::getInstance()->initActiveRecordByType();
234  "adv_md_values",
235  array("field_id" => array("integer", $a_field_id)),
236  $a_adt->getType()
237  );
238  }
239 
245  public static function _deleteByObjId($a_obj_id)
246  {
247  ilADTFactory::getInstance()->initActiveRecordByType();
249  "adv_md_values",
250  array("obj_id" => array("integer", $a_obj_id))
251  );
252  }
253 
254 
255 
256  //
257  // substitutions (aka list gui)
258  //
259 
265  public static function preloadByObjIds(array $a_obj_ids)
266  {
267  global $DIC;
268 
269  $ilDB = $DIC['ilDB'];
270 
271  // preload values
272  ilADTFactory::getInstance()->initActiveRecordByType();
274  "adv_md_values",
275  array("obj_id" => array("integer", $a_obj_ids))
276  );
277 
278 
279  // preload record ids for object types
280 
281  self::$preload_obj_records = array();
282 
283  // get active records for object types
284  $query = "SELECT amro.*" .
285  " FROM adv_md_record_objs amro" .
286  " JOIN adv_md_record amr ON (amr.record_id = amro.record_id)" .
287  " WHERE active = " . $ilDB->quote(1, "integer");
288  $set = $ilDB->query($query);
289  while ($row = $ilDB->fetchAssoc($set)) {
290  self::$preload_obj_records[$row["obj_type"]][] = array($row["record_id"], $row["optional"]);
291  }
292  }
293 
294  public static function preloadedRead($a_type, $a_obj_id)
295  {
296  $res = array();
297 
298  if (isset(self::$preload_obj_records[$a_type])) {
299  foreach (self::$preload_obj_records[$a_type] as $item) {
300  $record_id = $item[0];
301 
302  // record is optional, check activation for object
303  if ($item[1]) {
304  $found = false;
305  include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php";
306  foreach (ilAdvancedMDRecord::_getSelectedRecordsByObject($a_type, $a_obj_id) as $record) {
307  if ($record->getRecordId() == $item[0]) {
308  $found = true;
309  }
310  }
311  if (!$found) {
312  continue;
313  }
314  }
315 
316  $res[$record_id] = new self($record_id, $a_obj_id);
317  $res[$record_id]->read();
318  }
319  }
320 
321  return $res;
322  }
323 
324 
325  //
326  // copy/export (import: ilAdvancedMDValueParser)
327  //
328 
338  public static function _cloneValues($a_source_id, $a_target_id, $a_sub_type = null, $a_source_sub_id = null, $a_target_sub_id = null)
339  {
340  global $DIC;
341 
342  $ilLog = $DIC['ilLog'];
343 
344  // clone local records
345 
346  // new records are created automatically, only if source and target id differs.
347  include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php";
348  $new_records = $fields_map = array();
349 
350  foreach (ilAdvancedMDRecord::_getRecords() as $record) {
351  if ($record->getParentObject() == $a_source_id) {
352  $tmp = array();
353  if ($a_source_id != $a_target_id) {
354  $new_records[$record->getRecordId()] = $record->_clone($tmp, $a_target_id);
355  } else {
356  $new_records[$record->getRecordId()] = $record->getRecordId();
357  }
358  $fields_map[$record->getRecordId()] = $tmp;
359  }
360  }
361 
362 
363  // object record selection
364 
365  $source_sel = ilAdvancedMDRecord::getObjRecSelection($a_source_id, $a_sub_type);
366  if ($source_sel) {
367  $target_sel = array();
368  foreach ($source_sel as $record_id) {
369  // (local) record has been cloned
370  if (array_key_exists($record_id, $new_records)) {
371  $record_id = $new_records[$record_id]->getRecordId();
372  }
373  $target_sel[] = $record_id;
374  }
375  ilAdvancedMDRecord::saveObjRecSelection($a_target_id, $a_sub_type, $target_sel);
376  }
377 
378  // clone values
379 
380  $source_primary = array("obj_id" => array("integer", $a_source_id));
381  $target_primary = array("obj_id" => array("integer", $a_target_id));
382 
383  // sub-type support
384  if ($a_sub_type &&
385  $a_source_sub_id &&
386  $a_target_sub_id) {
387  $source_primary["sub_type"] = array("text", $a_sub_type);
388  $source_primary["sub_id"] = array("integer", $a_source_sub_id);
389  $target_primary["sub_type"] = array("text", $a_sub_type);
390  $target_primary["sub_id"] = array("integer", $a_target_sub_id);
391  }
392 
393  ilADTFactory::getInstance()->initActiveRecordByType();
395  "adv_md_values",
396  array(
397  "obj_id" => "integer",
398  "sub_type" => "text",
399  "sub_id" => "integer",
400  "field_id" => "integer"
401  ),
402  $source_primary,
403  $target_primary,
404  array("disabled" => "integer")
405  );
406 
407 
408  // move values of local records to newly created fields
409 
410  foreach ($fields_map as $source_record_id => $fields) {
411  // just to make sure
412  if (array_key_exists($source_record_id, $new_records)) {
413  foreach ($fields as $source_field_id => $target_field_id) {
414  // delete entry for old field id (was cloned above)
415  $del_target_primary = $target_primary;
416  $del_target_primary["field_id"] = array("integer", $source_field_id);
417  ilADTActiveRecordByType::deleteByPrimary("adv_md_values", $del_target_primary);
418 
419  // create entry for new id
420  $fix_source_primary = $source_primary;
421  $fix_source_primary["field_id"] = array("integer", $source_field_id);
422  $fix_target_primary = $target_primary;
423  $fix_target_primary["field_id"] = array("integer", $target_field_id);
425  "adv_md_values",
426  array(
427  "obj_id" => "integer",
428  "sub_type" => "text",
429  "sub_id" => "integer",
430  "field_id" => "integer"
431  ),
432  $fix_source_primary,
433  $fix_target_primary,
434  array("disabled" => "integer")
435  );
436  }
437  }
438  }
439 
440  if (!$has_cloned) {
441  $ilLog->write(__METHOD__ . ': No advanced meta data found.');
442  } else {
443  $ilLog->write(__METHOD__ . ': Start cloning advanced meta data.');
444  }
445  return true;
446  }
447 
454  public static function _appendXMLByObjId(ilXmlWriter $a_xml_writer, $a_obj_id)
455  {
456  $a_xml_writer->xmlStartTag('AdvancedMetaData');
457 
458  self::preloadByObjIds(array($a_obj_id));
459  $values_records = self::preloadedRead(ilObject::_lookupType($a_obj_id), $a_obj_id);
460 
461  foreach ($values_records as $values_record) {
462  $defs = $values_record->getDefinitions();
463  foreach ($values_record->getADTGroup()->getElements() as $element_id => $element) {
464  $def = $defs[$element_id];
465 
466  $value = null;
467  if (!$element->isNull()) {
468  $value = $def->getValueForXML($element);
469  }
470 
471  $a_xml_writer->xmlElement(
472  'Value',
473  array('id' => $def->getImportId()),
474  $value
475  );
476  }
477  }
478 
479  $a_xml_writer->xmlEndTag('AdvancedMetaData');
480  }
481 
482 
483  //
484  // glossary (might be generic)
485  //
486 
493  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)
494  {
495  $results = array();
496 
497  if (!is_array($a_obj_id)) {
498  $a_obj_id = array($a_obj_id);
499  }
500 
501  $sub_obj_ids = array();
502  foreach ($a_records as $rec) {
503  $sub_obj_ids[] = $rec[$a_obj_subid_key];
504  }
505 
506  // preload adv data for object id(s)
507  ilADTFactory::getInstance()->initActiveRecordByType();
509  "adv_md_values",
510  array(
511  "obj_id" => array("integer", $a_obj_id),
512  "sub_type" => array("text", $a_subtype),
513  "sub_id" => array("integer", $sub_obj_ids)
514  )
515  );
516 
517  $record_groups = array();
518 
519  foreach ($a_records as $rec) {
520  $obj_id = (int) $rec[$a_obj_id_key];
521  $sub_id = $rec[$a_obj_subid_key];
522 
523  // get adv records
524  foreach (ilAdvancedMDRecord::_getSelectedRecordsByObject($adv_rec_obj_type, $adv_rec_obj_ref_id, $adv_rec_obj_subtype) as $adv_record) {
525  $record_id = $adv_record->getRecordId();
526 
527  if (!isset($record_groups[$record_id])) {
530  $record_groups[$record_id] = ilADTFactory::getInstance()->getDBBridgeForInstance($record_groups[$record_id]);
531  $record_groups[$record_id]->setTable("adv_md_values");
532  }
533 
534  // prepare ADT group for record id
535  $record_groups[$record_id]->setPrimary(array(
536  "obj_id" => array("integer", $obj_id),
537  "sub_type" => array("text", $a_subtype),
538  "sub_id" => array("integer", $sub_id)
539  ));
540  // multi-enum fakes single in adv md
541  foreach ($record_groups[$record_id]->getElements() as $element) {
542  if ($element->getADT()->getType() == "MultiEnum") {
543  $element->setFakeSingle(true);
544  }
545  }
546 
547  // read (preloaded) data
548  $active_record = new ilADTActiveRecordByType($record_groups[$record_id]);
549  $active_record->setElementIdColumn("field_id", "integer");
550  $active_record->read();
551 
552  $adt_group = $record_groups[$record_id]->getADT();
553 
554  // filter against amet values
555  if ($a_amet_filter) {
556  foreach ($a_amet_filter as $field_id => $element) {
557  if ($adt_group->hasElement($field_id)) {
558  if (!$element->isInCondition($adt_group->getElement($field_id))) {
559  continue(3);
560  }
561  }
562  }
563  }
564  // add amet values to glossary term record
565  foreach ($adt_group->getElements() as $element_id => $element) {
566  if (!$element->isNull()) {
567  // we are reusing the ADT group for all $a_records, so we need to clone
568  $pb = ilADTFactory::getInstance()->getPresentationBridgeForInstance(clone $element);
569  $rec["md_" . $element_id] = $pb->getSortable();
570  $rec["md_" . $element_id . "_presentation"] = $pb;
571  } else {
572  $rec["md_" . $element_id] = null;
573  }
574  }
575  }
576 
577  $results[] = $rec;
578  }
579 
580  return $results;
581  }
582 }
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.
ADT Active Record by type helper class.
static _getRecords()
Get records.
global $DIC
Definition: saml.php:7
static initActiveRecordByType()
Init active record by type.
static preloadByObjIds(array $a_obj_ids)
Preload list gui data.
$factory
Definition: metadata.php:43
if(!array_key_exists('StateId', $_REQUEST)) $id
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.
$records
Definition: simple_test.php:22
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.
$a_type
Definition: workflow.php:92
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)
static getInstancesByRecordId($a_record_id, $a_only_searchable=false)
Get definitions by record id.
foreach($_POST as $key=> $value) $res
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.
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.
getADTGroup()
Init ADT group for current record.
$query
static _lookupType($a_id, $a_reference=false)
lookup object type
$row
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?
write(array $a_additional_data=null)
Write record values.
read()
Get record values.
$results
Definition: svg-scanner.php:47
global $ilDB
$def
Definition: croninfo.php:21
static preloadedRead($a_type, $a_obj_id)
static getObjRecSelection($a_obj_id, $a_sub_type="")
Get repository object record selection.
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.
$data
Definition: bench.php:6