ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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  include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php";
66  foreach (ilAdvancedMDRecord::_getSelectedRecordsByObject($a_obj_type, $ref_id, $a_sub_type) as $record) {
67  $id = $record->getRecordId();
68 
69  if (!isset($res[$id])) {
70  $res[$id] = new self($id, $a_obj_id, $a_sub_type, $a_sub_id);
71  }
72  }
73  }
74  return $res;
75  }
76 
84  public function setActiveRecordPrimary($a_obj_id, $a_sub_type = "-", $a_sub_id = 0)
85  {
86  $this->obj_id = (int) $a_obj_id;
87  $this->sub_type = $a_sub_type ? $a_sub_type : "-";
88  $this->sub_id = (int) $a_sub_id;
89 
90  // make sure they get used
91  $this->active_record = null;
92  }
93 
99  public function getDefinitions()
100  {
101  if (!is_array($this->defs)) {
102  $this->defs = ilAdvancedMDFieldDefinition::getInstancesByRecordId($this->record_id);
103  }
104  return $this->defs;
105  }
106 
112  public function getADTGroup()
113  {
114  if (!$this->adt_group instanceof ilADTGroup) {
116  }
117  return $this->adt_group;
118  }
119 
125  protected function getActiveRecord()
126  {
127  if (!$this->active_record instanceof ilADTActiveRecordByType) {
128  include_once "Services/ADT/classes/class.ilADTFactory.php";
130 
131  $adt_group_db = $factory->getDBBridgeForInstance($this->getADTGroup());
132 
133  $primary = array(
134  "obj_id" => array("integer", $this->obj_id),
135  "sub_type" => array("text", $this->sub_type),
136  "sub_id" => array("integer", $this->sub_id)
137  );
138  $adt_group_db->setPrimary($primary);
139  $adt_group_db->setTable("adv_md_values");
140 
141  // multi-enum fakes single in adv md
142  foreach ($adt_group_db->getElements() as $element) {
143  if ($element->getADT()->getType() == "MultiEnum") {
144  $element->setFakeSingle(true);
145  }
146  }
147 
148  $this->active_record = $factory->getActiveRecordByTypeInstance($adt_group_db);
149  $this->active_record->setElementIdColumn("field_id", "integer");
150  }
151 
152  return $this->active_record;
153  }
154 
161  public static function findByObjectId($a_obj_id)
162  {
163  include_once "Services/ADT/classes/class.ilADTFactory.php";
165  return ilADTActiveRecordByType::readByPrimary("adv_md_values", array("obj_id"=>array("integer", $a_obj_id)));
166  }
167 
168 
169  //
170  // disabled
171  //
172 
173  // to set disabled use self::write() with additional data
174 
181  public function isDisabled($a_element_id)
182  {
183  if (is_array($this->disabled)) {
184  return in_array($a_element_id, $this->disabled);
185  }
186  }
187 
188 
189  //
190  // CRUD
191  //
192 
196  public function read()
197  {
198  $this->disabled = array();
199 
200  $tmp = $this->getActiveRecord()->read(true);
201  if ($tmp) {
202  foreach ($tmp as $element_id => $data) {
203  if ($data["disabled"]) {
204  $this->disabled[] = $element_id;
205  }
206  }
207  }
208  }
209 
215  public function write(array $a_additional_data = null)
216  {
217  $this->getActiveRecord()->write($a_additional_data);
218  }
219 
227  public static function _deleteByFieldId($a_field_id, ilADT $a_adt)
228  {
229  ilADTFactory::getInstance()->initActiveRecordByType();
231  "adv_md_values",
232  array("field_id"=>array("integer", $a_field_id)),
233  $a_adt->getType()
234  );
235  }
236 
242  public static function _deleteByObjId($a_obj_id)
243  {
244  ilADTFactory::getInstance()->initActiveRecordByType();
246  "adv_md_values",
247  array("obj_id"=>array("integer", $a_obj_id))
248  );
249  }
250 
251 
252 
253  //
254  // substitutions (aka list gui)
255  //
256 
262  public static function preloadByObjIds(array $a_obj_ids)
263  {
264  global $ilDB;
265 
266  // preload values
267  ilADTFactory::getInstance()->initActiveRecordByType();
269  "adv_md_values",
270  array("obj_id"=>array("integer", $a_obj_ids))
271  );
272 
273 
274  // preload record ids for object types
275 
276  self::$preload_obj_records = array();
277 
278  // get active records for object types
279  $query = "SELECT amro.*" .
280  " FROM adv_md_record_objs amro" .
281  " JOIN adv_md_record amr ON (amr.record_id = amro.record_id)" .
282  " WHERE active = " . $ilDB->quote(1, "integer");
283  $set = $ilDB->query($query);
284  while ($row = $ilDB->fetchAssoc($set)) {
285  self::$preload_obj_records[$row["obj_type"]][] = array($row["record_id"], $row["optional"]);
286  }
287  }
288 
289  public static function preloadedRead($a_type, $a_obj_id)
290  {
291  $res = array();
292 
293  if (isset(self::$preload_obj_records[$a_type])) {
294  foreach (self::$preload_obj_records[$a_type] as $item) {
295  $record_id = $item[0];
296 
297  // record is optional, check activation for object
298  if ($item[1]) {
299  $found = false;
300  include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php";
301  foreach (ilAdvancedMDRecord::_getSelectedRecordsByObject($a_type, $a_obj_id) as $record) {
302  if ($record->getRecordId() == $item[0]) {
303  $found = true;
304  }
305  }
306  if (!$found) {
307  continue;
308  }
309  }
310 
311  $res[$record_id] = new self($record_id, $a_obj_id);
312  $res[$record_id]->read();
313  }
314  }
315 
316  return $res;
317  }
318 
319 
320  //
321  // copy/export (import: ilAdvancedMDValueParser)
322  //
323 
333  public static function _cloneValues($a_source_id, $a_target_id, $a_sub_type = null, $a_source_sub_id = null, $a_target_sub_id=null)
334  {
335  global $ilLog;
336 
337  // clone local records
338 
339  // new records are created automatically, only if source and target id differs.
340  include_once "Services/AdvancedMetaData/classes/class.ilAdvancedMDRecord.php";
341  $new_records = $fields_map = array();
342 
343  foreach (ilAdvancedMDRecord::_getRecords() as $record) {
344  if ($record->getParentObject() == $a_source_id) {
345  $tmp = array();
346  if ($a_source_id != $a_target_id) {
347  $new_records[$record->getRecordId()] = $record->_clone($tmp, $a_target_id);
348  } else {
349  $new_records[$record->getRecordId()] = $record->getRecordId();
350  }
351  $fields_map[$record->getRecordId()] = $tmp;
352  }
353  }
354 
355 
356  // object record selection
357 
358  $source_sel = ilAdvancedMDRecord::getObjRecSelection($a_source_id, $a_sub_type);
359  if ($source_sel) {
360  $target_sel = array();
361  foreach ($source_sel as $record_id) {
362  // (local) record has been cloned
363  if (array_key_exists($record_id, $new_records)) {
364  $record_id = $new_records[$record_id]->getRecordId();
365  }
366  $target_sel[] = $record_id;
367  }
368  ilAdvancedMDRecord::saveObjRecSelection($a_target_id, $a_sub_type, $target_sel);
369  }
370 
371  // clone values
372 
373  $source_primary = array("obj_id"=>array("integer", $a_source_id));
374  $target_primary = array("obj_id"=>array("integer", $a_target_id));
375 
376  // sub-type support
377  if ($a_sub_type &&
378  $a_source_sub_id &&
379  $a_target_sub_id) {
380  $source_primary["sub_type"] = array("text", $a_sub_type);
381  $source_primary["sub_id"] = array("integer", $a_source_sub_id);
382  $target_primary["sub_type"] = array("text", $a_sub_type);
383  $target_primary["sub_id"] = array("integer", $a_target_sub_id);
384  }
385 
386  ilADTFactory::getInstance()->initActiveRecordByType();
388  "adv_md_values",
389  array(
390  "obj_id" => "integer",
391  "sub_type" => "text",
392  "sub_id" => "integer",
393  "field_id" => "integer"
394  ),
395  $source_primary,
396  $target_primary,
397  array("disabled"=>"integer")
398  );
399 
400 
401  // move values of local records to newly created fields
402 
403  foreach ($fields_map as $source_record_id => $fields) {
404  // just to make sure
405  if (array_key_exists($source_record_id, $new_records)) {
406  foreach ($fields as $source_field_id => $target_field_id) {
407  // delete entry for old field id (was cloned above)
408  $del_target_primary = $target_primary;
409  $del_target_primary["field_id"] = array("integer", $source_field_id);
410  ilADTActiveRecordByType::deleteByPrimary("adv_md_values", $del_target_primary);
411 
412  // create entry for new id
413  $fix_source_primary = $source_primary;
414  $fix_source_primary["field_id"] = array("integer", $source_field_id);
415  $fix_target_primary = $target_primary;
416  $fix_target_primary["field_id"] = array("integer", $target_field_id);
418  "adv_md_values",
419  array(
420  "obj_id" => "integer",
421  "sub_type" => "text",
422  "sub_id" => "integer",
423  "field_id" => "integer"
424  ),
425  $fix_source_primary,
426  $fix_target_primary,
427  array("disabled"=>"integer")
428  );
429  }
430  }
431  }
432 
433  if (!$has_cloned) {
434  $ilLog->write(__METHOD__ . ': No advanced meta data found.');
435  } else {
436  $ilLog->write(__METHOD__ . ': Start cloning advanced meta data.');
437  }
438  return true;
439  }
440 
447  public static function _appendXMLByObjId(ilXmlWriter $a_xml_writer, $a_obj_id)
448  {
449  $a_xml_writer->xmlStartTag('AdvancedMetaData');
450 
451  self::preloadByObjIds(array($a_obj_id));
452  $values_records = self::preloadedRead(ilObject::_lookupType($a_obj_id), $a_obj_id);
453 
454  foreach ($values_records as $values_record) {
455  $defs = $values_record->getDefinitions();
456  foreach ($values_record->getADTGroup()->getElements() as $element_id => $element) {
457  $def = $defs[$element_id];
458 
459  $value = null;
460  if (!$element->isNull()) {
461  $value = $def->getValueForXML($element);
462  }
463 
464  $a_xml_writer->xmlElement(
465  'Value',
466  array('id' => $def->getImportId()),
467  $value
468  );
469  }
470  }
471 
472  $a_xml_writer->xmlEndTag('AdvancedMetaData');
473  }
474 
475 
476  //
477  // glossary (might be generic)
478  //
479 
486  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)
487  {
488  $results = array();
489 
490  if (!is_array($a_obj_id)) {
491  $a_obj_id = array($a_obj_id);
492  }
493 
494  $sub_obj_ids = array();
495  foreach ($a_records as $rec) {
496  $sub_obj_ids[] = $rec[$a_obj_subid_key];
497  }
498 
499  // preload adv data for object id(s)
500  ilADTFactory::getInstance()->initActiveRecordByType();
502  "adv_md_values",
503  array(
504  "obj_id" => array("integer", $a_obj_id),
505  "sub_type" => array("text", $a_subtype),
506  "sub_id" => array("integer", $sub_obj_ids)
507  )
508  );
509 
510  $record_groups = array();
511 
512  foreach ($a_records as $rec) {
513  $obj_id = $rec[$a_obj_id_key];
514  $sub_id = $rec[$a_obj_subid_key];
515 
516  // only active amet records for glossary
517  foreach (ilAdvancedMDRecord::_getSelectedRecordsByObject($adv_rec_obj_type, $adv_rec_obj_ref_id, $adv_rec_obj_subtype) as $adv_record) {
518  $record_id = $adv_record->getRecordId();
519 
520  if (!isset($record_groups[$record_id])) {
523  $record_groups[$record_id] = ilADTFactory::getInstance()->getDBBridgeForInstance($record_groups[$record_id]);
524  $record_groups[$record_id]->setTable("adv_md_values");
525  }
526 
527  // prepare ADT group for record id
528  $record_groups[$record_id]->setPrimary(array(
529  "obj_id" => array("integer", $obj_id),
530  "sub_type" => array("text", $a_subtype),
531  "sub_id" => array("integer", $sub_id)
532  ));
533 
534  // multi-enum fakes single in adv md
535  foreach ($record_groups[$record_id]->getElements() as $element) {
536  if ($element->getADT()->getType() == "MultiEnum") {
537  $element->setFakeSingle(true);
538  }
539  }
540 
541  // read (preloaded) data
542  $active_record = new ilADTActiveRecordByType($record_groups[$record_id]);
543  $active_record->setElementIdColumn("field_id", "integer");
544  $active_record->read();
545 
546  $adt_group = $record_groups[$record_id]->getADT();
547 
548  // filter against amet values
549  if ($a_amet_filter) {
550  foreach ($a_amet_filter as $field_id => $element) {
551  if ($adt_group->hasElement($field_id)) {
552  if (!$element->isInCondition($adt_group->getElement($field_id))) {
553  continue(3);
554  }
555  }
556  }
557  }
558  // add amet values to glossary term record
559  foreach ($adt_group->getElements() as $element_id => $element) {
560  if (!$element->isNull()) {
561  // we are reusing the ADT group for all $a_records, so we need to clone
562  $pb = ilADTFactory::getInstance()->getPresentationBridgeForInstance(clone $element);
563  $rec["md_" . $element_id] = $pb->getSortable();
564  $rec["md_" . $element_id . "_presentation"] = $pb;
565  } else {
566  $rec["md_" . $element_id] = null;
567  }
568  }
569  }
570 
571  $results[] = $rec;
572  }
573 
574  return $results;
575  }
576 }
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.
static initActiveRecordByType()
Init active record by type.
static preloadByObjIds(array $a_obj_ids)
Preload list gui data.
$factory
Definition: metadata.php:47
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.
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
Create styles array
The data for the language used.
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?
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.