ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
SeqTreeBuilder.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
21 /*
22  PHP port of several ADL-sources
23  @author Hendrik Holtmann <holtmann@mac.com>
24 
25  This .php file is GPL licensed (see above) but based on
26  Sourcecode by ADL Co-Lab, which is licensed as:
27 
28  Advanced Distributed Learning Co-Laboratory (ADL Co-Lab) Hub grants you
29  ("Licensee") a non-exclusive, royalty free, license to use, modify and
30  redistribute this software in source and binary code form, provided that
31  i) this copyright notice and license appear on all copies of the software;
32  and ii) Licensee does not utilize the software in a manner which is
33  disparaging to ADL Co-Lab Hub.
34 
35  This software is provided "AS IS," without a warranty of any kind. ALL
36  EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
37  ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
38  OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ADL Co-Lab Hub AND ITS LICENSORS
39  SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
40  USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO
41  EVENT WILL ADL Co-Lab Hub OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE,
42  PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
43  INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE
44  THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE
45  SOFTWARE, EVEN IF ADL Co-Lab Hub HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
46  DAMAGES.
47 */
48 
49 require_once("SeqActivity.php");
50 
51 require_once("SeqRule.php");
52 require_once("SeqRuleset.php");
53 
54 require_once("SeqCondition.php");
55 require_once("SeqConditionSet.php");
56 
57 require_once("SeqObjective.php");
58 require_once("SeqObjectiveMap.php");
59 
60 require_once("SeqRollupRule.php");
61 require_once("SeqRollupRuleset.php");
62 
63 require_once("ADLAuxiliaryResource.php");
64 
66 {
67  public function buildNodeSeqTree(string $file): array
68  {
69  $doc = new DomDocument();
70  $doc->load($file);
71  $organizations = $doc->getElementsByTagName("organizations");
72 
73  //lookup default organization id
74  $item = $organizations->item(0);
75  if ($item !== null) {
76  $default = preg_replace('/(%20)+/', ' ', trim($item->getAttribute("default")));
77  }
78 
79  //get all organization nodes
80  $organization = $doc->getElementsByTagName("organization");
81 
82  //lookup the default organization
83  foreach ($organization as $element) {
84  if (preg_replace('/(%20)+/', ' ', trim($element->getAttribute("identifier"))) == $default) {
85  $default_organization = $element;
86  }
87  }
88 
89  //read seqCollection
90  $seqCollection = $doc->getElementsByTagName("sequencingCollection")->item(0);
91 
92  $root = $this->buildNode($default_organization, $seqCollection, $doc);
93 
94  //return no data please check
95  $objectivesGlobalToSystem = $default_organization->getAttributeNS("http://www.adlnet.org/xsd/adlseq_v1p3", "objectivesGlobalToSystem");
96 
97  $org = preg_replace('/(%20)+/', ' ', trim($default_organization->getAttribute("identifier")));
98 
99  //default true
100  $globaltosystem = 1;
101 
102  if ($objectivesGlobalToSystem === "false") {
103  $globaltosystem = 0;
104  }
105 
106  //return no data please check
107  $dataGlobalToSystem = $default_organization->getAttributeNS("http://www.adlnet.org/xsd/adlcp_v1p3", "sharedDataGlobalToSystem");
108 
109  //default true
110  $dataglobaltosystem = 1;
111 
112  if ($dataGlobalToSystem === "false") {
113  $dataglobaltosystem = 0;
114  }
115 
116  //assign SeqActivity to top node
117  $c_root['_SeqActivity'] = $root;
118 
119  $ret['global'] = $globaltosystem;
120  $ret['dataglobal'] = $dataglobaltosystem;
121  $ret['tree'] = $c_root;
122 
123  return $ret;
124  }
125 
126 
127 
128  private function buildNode(object $node, ?object $seq, object $doc): SeqActivity
129  {
130  //create a new activity object
131  $act = new SeqActivity();
132 
133  //set various attributes, if existent
134  $act->setID(preg_replace('/(%20)+/', ' ', trim($node->getAttribute("identifier"))));
135 
136  $tempVal = preg_replace('/(%20)+/', ' ', trim($node->getAttribute("identifierref")));
137  if ($tempVal) {
138  $act->setResourceID($tempVal);
139  }
140 
141  $tempVal = $node->getAttribute("isvisible");
142 
143  if ($tempVal) {
144  $act->setIsVisible(self::convert_to_bool($tempVal));
145  }
146 
147 
148 
149  //Proceed nested items
150  $children = $node->childNodes;
151 
152  for ($i = 0; $i < $children->length; $i++) {
153  $curNode = $children->item($i);
154  //elements only
155 
156  if ($curNode->nodeType == XML_ELEMENT_NODE) {
157  //only items are nested
158  if ($curNode->localName === "item") {
159  //init;
160  $c_nestedAct = null;
161  $nestedAct = $this->buildNode($curNode, $seq, $doc);
162  if ($nestedAct != null) {
163  $act->AddChild((object) $nestedAct);
164  }
165  } elseif ($curNode->localName === "title") {
166  $act->setTitle(self::lookupElement($curNode, null));
167  } elseif ($curNode->localName === "completionThreshold") {
168  $tempVal = $curNode->getAttribute("minProgressMeasure");
169 
170  if ($tempVal) {
171  $act->setCompletionThreshold($tempVal);
172  } elseif ($curNode->nodeValue != null && $curNode->nodeValue != '') {
173  $act->setCompletionThreshold((float) $curNode->nodeValue);
174  }
175 
176  $tempVal = $curNode->getAttribute("progressWeight");
177 
178  if ($tempVal) {
179  $act->setProgressWeight($tempVal);
180  }
181  $tempVal = $curNode->getAttribute("completedByMeasure");
182 
183  if ($tempVal) {
184  $act->setCompletedByMeasure(self::convert_to_bool($tempVal));
185  }
186  } elseif ($curNode->localName === "sequencing") {
187  $seqInfo = $curNode;
188  //get IDRef
189  $tempVal = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("IDRef")));
190  //only execute for referenced sequencing parts
191  if ($tempVal) {
192  //init seqGlobal
193  $seqGlobal = null;
194 
195  //get all sequencing nodes in collections
196  $sequencing = $seq->getElementsByTagName("sequencing");
197 
198  //lookup the matching sequencing element
199  foreach ($sequencing as $element) {
200  if (preg_replace('/(%20)+/', ' ', trim($element->getAttribute("ID"))) == $tempVal) {
201  $seqGlobal = $element;
202  }
203  }
204 
205  //clone the global node
206  $seqInfo = $seqGlobal->cloneNode(true);
207 
208  //back to the local node
209  $seqChildren = $curNode->childNodes;
210  for ($j = 0; $j < $seqChildren->length; $j++) {
211  //process local nodes
212  $curChild = $seqChildren->item($j);
213  if ($curChild->nodeType == XML_ELEMENT_NODE) {
214  //echo "\nFound Sequencing Element Node".$curChild->localName;
215  //add local to global sequencing info
216  $seqInfo->appendChild($curChild);
217  }
218  }
219  }
220  //extract the sequencing info, if we have one
221  //avoid working with
222  $act = $this->extractSeqInfo($seqInfo, $act);
223  }
224  }
225 
226 
227 
228  $item = $children->item($i)->nodeValue;
229  }
230  //add class
231  //$c_act['_SeqActivity']=$act;
232  return $act;
233  }
234 
235 
236  private function extractSeqInfo(object $iNode, object $ioAct): object
237  {
238  //set sequencing information
239  $children = $iNode->childNodes;
240  for ($i = 0; $i < $children->length; $i++) {
241  $curNode = $children->item($i);
242  if ($curNode->nodeType == XML_ELEMENT_NODE) {
243  if ($curNode->localName === "controlMode") {
244  //look for choice
245  $tempVal = $curNode->getAttribute("choice");
246  if ($tempVal) {
247  $ioAct->setControlModeChoice(self::convert_to_bool($tempVal));
248  }
249  //look for choiceExit
250  $tempVal = $curNode->getAttribute("choiceExit");
251  if ($tempVal) {
252  $ioAct->setControlModeChoiceExit(self::convert_to_bool($tempVal));
253  }
254 
255  //look for flow
256  $tempVal = $curNode->getAttribute("flow");
257  if ($tempVal) {
258  $ioAct->setControlModeFlow(self::convert_to_bool($tempVal));
259  }
260 
261  // Look for 'forwardOnly'
262  $tempVal = $curNode->getAttribute("forwardOnly");
263  if ($tempVal) {
264  $ioAct->setControlForwardOnly(self::convert_to_bool($tempVal));
265  }
266 
267  // Look for 'useCurrentAttemptObjectiveInfo'
268  $tempVal = $curNode->getAttribute("useCurrentAttemptObjectiveInfo");
269  if ($tempVal) {
270  $ioAct->setUseCurObjective(self::convert_to_bool($tempVal));
271  }
272 
273  // Look for 'useCurrentAttemptProgressInfo'
274  $tempVal = $curNode->getAttribute("useCurrentAttemptProgressInfo");
275  if ($tempVal) {
276  $ioAct->setUseCurProgress(self::convert_to_bool($tempVal));
277  }
278  } elseif ($curNode->localName === "sequencingRules") {
279  $ioAct = self::getSequencingRules($curNode, $ioAct);
280  } elseif ($curNode->localName === "limitConditions") {
281  // Look for 'useCurrentAttemptObjectiveInfo'
282  $tempVal = $curNode->getAttribute("attemptLimit");
283  if ($tempVal) {
284  $ioAct->setAttemptLimit($tempVal);
285  }
286 
287  // Look for 'attemptAbsoluteDurationLimit'
288  $tempVal = $curNode->getAttribute("attemptAbsoluteDurationLimit");
289  if ($tempVal) {
290  $ioAct->setAttemptAbDur($tempVal);
291  }
292 
293  // Look for 'attemptExperiencedDurationLimit'
294  $tempVal = $curNode->getAttribute("attemptExperiencedDurationLimit");
295  if ($tempVal) {
296  $ioAct->setAttemptExDur($tempVal);
297  }
298 
299  // Look for 'activityAbsoluteDurationLimit'
300  $tempVal = $curNode->getAttribute("activityAbsoluteDurationLimit");
301  if ($tempVal) {
302  $ioAct->setActivityAbDur($tempVal);
303  }
304 
305  // Look for 'activityExperiencedDurationLimit'
306  $tempVal = $curNode->getAttribute("activityExperiencedDurationLimit");
307  if ($tempVal) {
308  $ioAct->setActivityExDur($tempVal);
309  }
310 
311  // Look for 'beginTimeLimit'
312  $tempVal = $curNode->getAttribute("beginTimeLimit");
313  if ($tempVal) {
314  $ioAct->setBeginTimeLimit($tempVal);
315  }
316 
317  // Look for 'endTimeLimit'
318  $tempVal = $curNode->getAttribute("endTimeLimit");
319  if ($tempVal) {
320  $ioAct->setEndTimeLimit($tempVal);
321  }
322  } elseif ($curNode->localName === "auxiliaryResources") {
323  $ioAct = self::getAuxResources($curNode, $ioAct);
324  } elseif ($curNode->localName === "rollupRules") {
325  $ioAct = self::getRollupRules($curNode, $ioAct);
326  } elseif ($curNode->localName === "objectives" && $curNode->namespaceURI === "http://www.imsglobal.org/xsd/imsss") {
327  $ioAct = self::getObjectives($curNode, $ioAct);
328  } elseif ($curNode->localName === "objectives" && $curNode->namespaceURI === "http://www.adlnet.org/xsd/adlseq_v1p3") {
329  $ioAct = self::getADLSEQObjectives($curNode, $ioAct);
330  } elseif ($curNode->localName === "randomizationControls") {
331  // Look for 'randomizationTiming'
332  $tempVal = $curNode->getAttribute("randomizationTiming");
333  if ($tempVal) {
334  $ioAct->setRandomTiming($tempVal);
335  }
336 
337  // Look for 'selectCount'
338  $tempVal = $curNode->getAttribute("selectCount");
339  if ($tempVal) {
340  $ioAct->setSelectCount($tempVal);
341  }
342 
343  // Look for 'reorderChildren'
344  $tempVal = $curNode->getAttribute("reorderChildren");
345  if ($tempVal) {
346  $ioAct->setReorderChildren(self::convert_to_bool($tempVal));
347  }
348 
349  // Look for 'selectionTiming'
350  $tempVal = $curNode->getAttribute("selectionTiming");
351  if ($tempVal) {
352  $ioAct->setSelectionTiming($tempVal);
353  }
354  } elseif ($curNode->localName === "deliveryControls") {
355  // Look for 'tracked'
356  $tempVal = $curNode->getAttribute("tracked");
357  if ($tempVal) {
358  $ioAct->setIsTracked(self::convert_to_bool($tempVal));
359  }
360 
361  // Look for 'completionSetByContent'
362  $tempVal = $curNode->getAttribute("completionSetByContent");
363  if ($tempVal) {
364  $ioAct->setSetCompletion(self::convert_to_bool($tempVal));
365  }
366 
367  // Look for 'objectiveSetByContent'
368  $tempVal = $curNode->getAttribute("objectiveSetByContent");
369  if ($tempVal) {
370  $ioAct->setSetObjective(self::convert_to_bool($tempVal));
371  }
372  } elseif ($curNode->localName === "constrainedChoiceConsiderations") {
373  // Look for 'preventActivation'
374  $tempVal = $curNode->getAttribute("preventActivation");
375  if ($tempVal) {
376  $ioAct->setPreventActivation(self::convert_to_bool($tempVal));
377  }
378 
379  // Look for 'constrainChoice'
380  $tempVal = $curNode->getAttribute("constrainChoice");
381  if ($tempVal) {
382  $ioAct->setConstrainChoice(self::convert_to_bool($tempVal));
383  }
384  } elseif ($curNode->localName === "rollupConsiderations") {
385  // Look for 'requiredForSatisfied'
386  $tempVal = $curNode->getAttribute("requiredForSatisfied");
387  if ($tempVal) {
388  $ioAct->setRequiredForSatisfied($tempVal);
389  }
390 
391  // Look for 'requiredForNotSatisfied'
392  $tempVal = $curNode->getAttribute("requiredForNotSatisfied");
393  if ($tempVal) {
394  $ioAct->setRequiredForNotSatisfied($tempVal);
395  }
396 
397  // Look for 'requiredForCompleted'
398  $tempVal = $curNode->getAttribute("requiredForCompleted");
399  if ($tempVal) {
400  $ioAct->setRequiredForCompleted($tempVal);
401  }
402 
403  // Look for 'requiredForIncomplete'
404  $tempVal = $curNode->getAttribute("requiredForIncomplete");
405  if ($tempVal) {
406  $ioAct->setRequiredForIncomplete($tempVal);
407  }
408 
409  // Look for 'measureSatisfactionIfActive'
410  $tempVal = $curNode->getAttribute("measureSatisfactionIfActive");
411  if ($tempVal) {
412  $ioAct->setSatisfactionIfActive(self::convert_to_bool($tempVal));
413  }
414  }
415  } //end note-type check
416  } //end for-loop
417 
418  return $ioAct;
419  }
420 
421 
422  public static function getObjectives(object $iNode, object $ioAct): object
423  {
424  global $DIC;
425  $ilLog = ilLoggerFactory::getLogger('sc13');
426 
427 
428  $ok = true;
429  $tempVal = null;
430  $objectives = array();
431  $children = $iNode->childNodes;
432  for ($i = 0; $i < $children->length; $i++) {
433  $curNode = $children->item($i);
434  if ($curNode->nodeType == XML_ELEMENT_NODE) {
435  if ($curNode->localName === "primaryObjective" || $curNode->localName === "objective") {
436  $obj = new SeqObjective();
437  if ($curNode->localName === "primaryObjective") {
438  $obj->mContributesToRollup = true;
439  }
440 
441  // Look for 'objectiveID'
442  $tempVal = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("objectiveID")));
443  if ($tempVal) {
444  $obj->mObjID = $tempVal;
445  }
446 
447  // Look for 'satisfiedByMeasure'
448  $tempVal = $curNode->getAttribute("satisfiedByMeasure");
449  if ($tempVal) {
450  $obj->mSatisfiedByMeasure = self::convert_to_bool($tempVal);
451  }
452  // Look for 'minNormalizedMeasure'
453  $tempVal = self::lookupElement($curNode, "minNormalizedMeasure");
454  if ($tempVal) {
455  $obj->mMinMeasure = (float) $tempVal;
456  }
457 
458  //get ObjectiveMaps
459  $maps = self::getObjectiveMaps($curNode);
460  if ($maps != null) {
461  $obj->mMaps = $maps;
462  }
463  //$obj->mContributesToRollup = true;
464  //add class
465  $c_obj['_SeqObjective'] = $obj;
466  $objectives[] = $c_obj;
467  }
468  }
469  }
470  $ioAct->setObjectives($objectives);
471  return $ioAct;
472  }
473 
474  public static function getADLSEQObjectives(object $iNode, object $ioAct): object
475  {
476  global $DIC;
477  $ilLog = ilLoggerFactory::getLogger('sc13');
478  $objectives = $ioAct->mObjectives;
479  $children = $iNode->childNodes;
480  for ($i = 0; $i < $children->length; $i++) {
481  $curNode = $children->item($i);
482  if ($curNode->nodeType == XML_ELEMENT_NODE) {
483  if ($curNode->localName === "objective") {
484  // get the objectiveID
485  $adlseqobjid = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("objectiveID")));
486 
487  // find the imsss objective with the same objectiveID
488  $curseqobj = null;
489  foreach ($objectives as $j => $value) {
490  $seqobj = $value['_SeqObjective'];
491  if ($seqobj->mObjID == $adlseqobjid) {
492  $curseqobj = $seqobj;
493  $curseqobjindex = $j;
494  break;
495  }
496  }
497 
498  // if there's a current seq then let's add the maps
499  if ($curseqobj != null) {
500  // for each adlseq map info populate that mMaps with map info in the adlseq objective
501  $curseqobj = self::getADLSeqMaps($curNode, $curseqobj);
502  $seqobj = $curseqobj;
503  $objectives[$curseqobjindex]['_SeqObjective'] = $seqobj;
504  }
505  }
506  }
507  }
508  // before i leave what do i have to duplicate in SeqActivity or some other class?
509  // prolly just
510  $ioAct->setObjectives($objectives);
511  return $ioAct;
512  }
513 
514  public static function getADLSeqMaps(object $iNode, object $curseqobj): object
515  {
516  if (count($curseqobj->mMaps) == null) {
517  $curseqobj->mMaps = array();
518  }
519  $maps = $curseqobj->mMaps;
520 
521  $children = $iNode->childNodes;
522  for ($i = 0; $i < $children->length; $i++) {
523  $curNode = $children->item($i);
524  if ($curNode->nodeType == XML_ELEMENT_NODE) {
525  if ($curNode->localName === "mapInfo") {
526  $map = new SeqObjectiveMap();
527  $curadltargetobjid = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("targetObjectiveID")));
528  // if the adl map target id matches an imsssssss one, then add to the imsssss one
529  $matchingmapindex = -1;
530  foreach ($maps as $j => $value) {
531  if ($value['_SeqObjectiveMap']->mGlobalObjID == $curadltargetobjid) {
532  $map = $value['_SeqObjectiveMap'];
533  $matchingmapindex = $j;
534  }
535  }
536  // tom: if default access is dependent on map existence then this will need to know if an imsss:mapInfo existed
537  $map = self::fillinADLSeqMaps($curNode, $map);
538 
539  $c_map['_SeqObjectiveMap'] = $map;
540  if ($matchingmapindex > -1) {
541  $maps[$matchingmapindex] = $c_map;
542  } else {
543  $maps[] = $c_map;
544  }
545  }
546  }
547  }
548  $curseqobj->mMaps = $maps;
549  return $curseqobj;
550  }
551 
552  public static function fillinADLSeqMaps(object $iNode, object $map): object
553  {
554  if ($map->mGlobalObjID == null) {
555  $map->mGlobalObjID = preg_replace('/(%20)+/', ' ', trim($iNode->getAttribute("targetObjectiveID")));
556  }
557 
558  $tempVal = $iNode->getAttribute("readRawScore");
559  if ($tempVal) {
560  $map->mReadRawScore = self::convert_to_bool($tempVal);
561  }
562 
563  $tempVal = $iNode->getAttribute("readMinScore");
564  if ($tempVal) {
565  $map->mReadMinScore = self::convert_to_bool($tempVal);
566  }
567 
568  $tempVal = $iNode->getAttribute("readMaxScore");
569  if ($tempVal) {
570  $map->mReadMaxScore = self::convert_to_bool($tempVal);
571  }
572 
573  $tempVal = $iNode->getAttribute("readCompletionStatus");
574  if ($tempVal) {
575  $map->mReadCompletionStatus = self::convert_to_bool($tempVal);
576  }
577 
578  $tempVal = $iNode->getAttribute("readProgressMeasure");
579  if ($tempVal) {
580  $map->mReadProgressMeasure = self::convert_to_bool($tempVal);
581  }
582 
583  $tempVal = $iNode->getAttribute("writeRawScore");
584  if ($tempVal) {
585  $map->mWriteRawScore = self::convert_to_bool($tempVal);
586  }
587 
588  $tempVal = $iNode->getAttribute("writeMinScore");
589  if ($tempVal) {
590  $map->mWriteMinScore = self::convert_to_bool($tempVal);
591  }
592 
593  $tempVal = $iNode->getAttribute("writeMaxScore");
594  if ($tempVal) {
595  $map->mWriteMaxScore = self::convert_to_bool($tempVal);
596  }
597 
598  $tempVal = $iNode->getAttribute("writeCompletionStatus");
599  if ($tempVal) {
600  $map->mWriteCompletionStatus = self::convert_to_bool($tempVal);
601  }
602 
603  $tempVal = $iNode->getAttribute("writeProgressMeasure");
604  if ($tempVal) {
605  $map->mWriteProgressMeasure = self::convert_to_bool($tempVal);
606  }
607 
608  return $map;
609  }
610 
611  public static function getObjectiveMaps(object $iNode): ?array
612  {
613  $tempVal = null;
614  $maps = array();
615  $children = $iNode->childNodes;
616  for ($i = 0; $i < $children->length; $i++) {
617  $curNode = $children->item($i);
618  if ($curNode->nodeType == XML_ELEMENT_NODE) {
619  if ($curNode->localName === "mapInfo") {
620  $map = new SeqObjectiveMap();
621 
622  // Look for 'targetObjectiveID'
623  $tempVal = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("targetObjectiveID")));
624  if ($tempVal) {
625  $map->mGlobalObjID = $tempVal;
626  }
627 
628  // Look for 'readSatisfiedStatus'
629  $tempVal = $curNode->getAttribute("readSatisfiedStatus");
630  if ($tempVal) {
631  $map->mReadStatus = self::convert_to_bool($tempVal);
632  }
633 
634  // Look for 'readNormalizedMeasure'
635  $tempVal = $curNode->getAttribute("readNormalizedMeasure");
636  if ($tempVal) {
637  $map->mReadMeasure = self::convert_to_bool($tempVal);
638  }
639 
640  // Look for 'writeSatisfiedStatus'
641  $tempVal = $curNode->getAttribute("writeSatisfiedStatus");
642  if ($tempVal) {
643  $map->mWriteStatus = self::convert_to_bool($tempVal);
644  }
645 
646  // Look for 'writeNormalizedMeasure'
647  $tempVal = $curNode->getAttribute("writeNormalizedMeasure");
648  if ($tempVal) {
649  $map->mWriteMeasure = self::convert_to_bool($tempVal);
650  }
651  //add class
652  $c_map['_SeqObjectiveMap'] = $map;
653  $maps[] = $c_map;
654  }
655  }
656  }
657  if (count($maps) == null) {
658  $maps = null;
659  }
660  return $maps;
661  }
662 
663  public static function getRollupRules(object $iNode, object $ioAct): object
664  {
665  $ok = true;
666  $tempVal = null;
667  $rollupRules = array();
668 
669  // Look for 'rollupObjectiveSatisfied'
670  $tempVal = $iNode->getAttribute("rollupObjectiveSatisfied");
671  if ($tempVal) {
672  $ioAct->setIsObjRolledUp(self::convert_to_bool($tempVal));
673  }
674 
675  // Look for 'objectiveMeasureWeight'
676  $tempVal = $iNode->getAttribute("objectiveMeasureWeight");
677  if ($tempVal) {
678  $ioAct->setObjMeasureWeight((float)$tempVal);
679  }
680  // Look for 'rollupProgressCompletion'
681  $tempVal = $iNode->getAttribute("rollupProgressCompletion");
682  if ($tempVal) {
683  $ioAct->setIsProgressRolledUp(self::convert_to_bool($tempVal));
684  }
685  $children = $iNode->childNodes;
686  for ($i = 0; $i < $children->length; $i++) {
687  $curNode = $children->item($i);
688  if ($curNode->nodeType == XML_ELEMENT_NODE) {
689  if ($curNode->localName === "rollupRule") {
690  $rule = new SeqRollupRule();
691 
692  // Look for 'childActivitySet'
693  $tempVal = $curNode->getAttribute("childActivitySet");
694  if ($tempVal) {
695  $rule->mChildActivitySet = $tempVal;
696  }
697  // Look for 'minimumCount'
698  $tempVal = $curNode->getAttribute("minimumCount");
699  if ($tempVal) {
700  $rule->mMinCount = $tempVal;
701  }
702 
703  // Look for 'minimumPercent'
704  $tempVal = $curNode->getAttribute("minimumPercent");
705  if ($tempVal) {
706  $rule->mMinPercent = $tempVal;
707  }
708  $rule->mConditions['_SeqConditionSet'] = new SeqConditionSet(true);
709  $conditions = array();
710  $ruleInfo = $curNode->childNodes;
711  for ($j = 0; $j < $ruleInfo->length; $j++) {
712  $curRule = $ruleInfo->item($j);
713  //check for element
714  if ($curRule->nodeType == XML_ELEMENT_NODE) {
715  if ($curRule->localName === "rollupConditions") {
716  $tempVal = $curRule->getAttribute("conditionCombination");
717  if ($tempVal) {
718  $rule->mConditions['_SeqConditionSet']->mCombination = $tempVal;
719  } else {
720  $rule->mConditions['_SeqConditionSet']->mCombination = COMBINATION_ANY;
721  }
722  $conds = $curRule->childNodes;
723  for ($k = 0; $k < $conds->length; $k++) {
724  $con = $conds->item($k);
725  if ($con->nodeType == XML_ELEMENT_NODE) {
726  if ($con->localName === "rollupCondition") {
727  $cond = new SeqCondition();
728  // Look for 'condition'
729  $tempVal = $con->getAttribute("condition");
730  if ($tempVal) {
731  $cond->mCondition = $tempVal;
732  }
733  // Look for 'operator'
734  $tempVal = $con->getAttribute("operator");
735  if ($tempVal) {
736  if ($tempVal === 'not') {
737  $cond->mNot = true;
738  } else {
739  $cond->mNot = false;
740  }
741  }
742  //add class
743  $c_cond['_SeqCondition'] = $cond;
744  $conditions[] = $c_cond;
745  }
746  }
747  }
748  } elseif ($curRule->localName === "rollupAction") {
749  $tempVal = $curRule->getAttribute("action");
750  if ($tempVal) {
751  $rule->setRollupAction($tempVal);
752  }
753  }
754  }
755  }
756  // Add the conditions to the condition set for the rule
757  $rule->mConditions['_SeqConditionSet']->mConditions = $conditions;
758 
759  // Add the rule to the ruleset
760  //add class
761  $c_rule['_SeqRollupRule'] = $rule;
762  $rollupRules[] = $c_rule;
763  }
764  }
765  }
766 
767  if ($rollupRules != null) {
768  $rules = new SeqRollupRuleset($rollupRules);
769  // Set the Activity's rollup rules
770  //add class
771  $c_rules['_SeqRollupRuleset'] = $rules;
772  $ioAct->setRollupRules($c_rules);
773  }
774 
775  return $ioAct;
776  }
777 
778 
779  public static function getSequencingRules(object $iNode, object $ioAct): object
780  {
781  //local variables
782  $ok = true;
783  $tempVal = null;
784 
785  $preRules = array();
786  $exitRules = array();
787  $postRules = array();
788 
789  //get children
790  $children = $iNode->childNodes;
791 
792  //find sequencing rules
793  for ($i = 0; $i < $children->length; $i++) {
794  $curNode = $children->item($i);
795  if ($curNode->nodeType == XML_ELEMENT_NODE) {
796  if ($curNode->localName === "preConditionRule" || $curNode->localName === "exitConditionRule" || $curNode->localName === "postConditionRule") {
797  $rule = new SeqRule();
798  $ruleInfo = $curNode->childNodes;
799  for ($j = 0; $j < $ruleInfo->length; $j++) {
800  $curRule = $ruleInfo->item($j);
801  //echo "$curRule->localName\n";
802  if ($curRule->nodeType == XML_ELEMENT_NODE) {
803  if ($curRule->localName === "ruleConditions") {
804  $rule->mConditions = self::extractSeqRuleConditions($curRule);
805  } elseif ($curRule->localName === "ruleAction") {
806  $tempVal = $curRule->getAttribute("action");
807  if ($tempVal) {
808  $rule->mAction = $tempVal;
809  }
810  }
811  }
812  }//end for inner
813  if ($rule->mConditions != null && $rule->mAction != null) {
814  //changed from ADL Code..
815  if ($curNode->localName === "preConditionRule") {
816  //echo "ADD PRE";
817  //add class
818  $c_rule['_SeqRule'] = $rule;
819  $preRules[] = $c_rule;
820  }
821  if ($curNode->localName === "exitConditionRule") {
822  //echo "ADD EXIT";
823  //add class
824  $c_rule['_SeqRule'] = $rule;
825  $exitRules[] = $c_rule;
826  }
827  if ($curNode->localName === "postConditionRule") {
828  //echo "ADD POST";
829  //add class
830  $c_rule['_SeqRule'] = $rule;
831  $postRules[] = $c_rule;
832  }
833  }
834  } //end if preCondition
835  } //end if ELEMENT
836  }
837 
838  if (count($preRules) > 0) {
839  $rules = new SeqRuleset($preRules);
840  //add class
841  $c_rules['_SeqRuleset'] = $rules;
842  $ioAct->setPreSeqRules($c_rules);
843  }
844 
845  if (count($exitRules) > 0) {
846  $rules = new SeqRuleset($exitRules);
847  //add class
848  $c_rules['_SeqRuleset'] = $rules;
849  $ioAct->setExitSeqRules($c_rules);
850  }
851  if (count($postRules) > 0) {
852  $rules = new SeqRuleset($postRules);
853  //add class
854  $c_rules['_SeqRuleset'] = $rules;
855  $ioAct->setPostSeqRules($c_rules);
856  }
857  //echo json_encode($ioAct);
858 
859  return $ioAct;
860  }
861 
862  public static function extractSeqRuleConditions(object $iNode): array
863  {
864  $tempVal = null;
865  $condSet = new SeqConditionSet(false);
866 
867  $conditions = array();
868  $tempVal = $iNode->getAttribute("conditionCombination");
869  if ($tempVal) {
870  $condSet->mCombination = $tempVal;
871  } else {
872  $condSet->mCombination = COMBINATION_ALL;
873  }
874  $condInfo = $iNode->childNodes;
875  for ($i = 0; $i < $condInfo->length; $i++) {
876  $curCond = $condInfo->item($i);
877  if ($curCond->nodeType == XML_ELEMENT_NODE) {
878  if ($curCond->localName === "ruleCondition") {
879  $cond = new SeqCondition();
880 
881  //look for condition
882  $tempVal = $curCond->getAttribute("condition");
883  if ($tempVal) {
884  $cond->mCondition = $tempVal;
885  }
886 
887  // Look for 'referencedObjective'
888  $tempVal = preg_replace('/(%20)+/', ' ', trim($curCond->getAttribute("referencedObjective")));
889  if ($tempVal) {
890  $cond->mObjID = $tempVal;
891  }
892 
893  // Look for 'measureThreshold'
894  $tempVal = $curCond->getAttribute("measureThreshold");
895  if ($tempVal) {
896  $cond->mThreshold = $tempVal;
897  }
898 
899  // Look for 'operator'
900  $tempVal = $curCond->getAttribute("operator");
901  if ($tempVal) {
902  if ($tempVal === 'not') {
903  $cond->mNot = true;
904  } else {
905  $cond->mNot = false;
906  }
907  }
908 
909  //add class
910  $c_cond['_SeqCondition'] = $cond;
911  $conditions[] = $c_cond;
912  }
913  }
914  }
915 
916  if (count($conditions) > 0) {
917  $condSet->mConditions = $conditions;
918  } else {
919  $condSet->mConditions = null;
920  }
921  //add class
922  $c_condSet['_SeqConditionSet'] = $condSet;
923  return $c_condSet;
924  }
925 
926  public static function getAuxResources(object $iNode, object $ioAct): object
927  {
928  $ok = true;
929  $tempVal = null;
930  $auxRes = array();
931  //get children
932  $children = $iNode->childNodes;
933 
934  //find ressources
935  for ($i = 0; $i < $children->length; $i++) {
936  $curNode = $children->item($i);
937  if ($curNode->nodeType == XML_ELEMENT_NODE) {
938  if ($curNode->localName === "auxiliaryResource") {
939  //found it
940  $res = new ADLAuxiliaryResource();
941 
942  // Get the resource's purpose
943  $tempVal = $curNode->getAttribute("purpose");
944  if ($tempVal) {
945  $res->mType = $tempVal;
946  }
947  // Get the resource's ID
948  $tempVal = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("auxiliaryResourceID")));
949  if ($tempVal) {
950  $res->mResourceID = $tempVal;
951  }
952  $auxRes[] = $res;
953  }
954  }
955  }
956  //add class
957  $c_auxRes['_ADLAuxiliaryResource'] = $auxRes;
958  $ioAct->setAuxResources($c_auxRes);
959  return $ioAct;
960  }
961 
962  //helper functions
963 
964  private static function convert_to_bool(string $string): bool
965  {
966  return strtoupper($string) !== "FALSE";
967  }
968 
969 
970  private static function lookupElement(object $iNode, ?string $iElement): ?string
971  {
972  $value = null;
973  $curNode = null;
974  $children = null;
975 
976  if ($iNode != null && $iElement != null) {
977  $children = $iNode->childNodes;
978  for ($i = 0; $i < $children->length; $i++) {
979  $curNode = $children->item($i);
980  if (($curNode->nodeType == XML_ELEMENT_NODE)) {
981  if ($curNode->localName == $iElement) {
982  break;
983  }
984  }
985  }
986  if ($curNode != null) {
987  $comp = $curNode->localName;
988  if ($comp != null) {
989  if ($comp != $iElement) {
990  $curNode = null;
991  }
992  } else {
993  $curNode = null;
994  }
995  }
996  } else {
997  //$iElement is null
998  $curNode = $iNode;
999  }
1000 
1001  if ($curNode != null) {
1002  $children = $curNode->childNodes;
1003  if ($children != null) {
1004  for ($i = 0; $i < $children->length; $i++) {
1005  $curNode = $children->item($i);
1006  // make sure we have a 'text' element
1007  if (($curNode->nodeType == XML_TEXT_NODE) || ($curNode->nodeType == XML_CDATA_SECTION_NODE)) {
1008  $value = $value . $curNode->nodeValue;
1009  }
1010  }
1011  }
1012  }
1013  return $value;
1014  }
1015 } //end class
$res
Definition: ltiservices.php:69
const COMBINATION_ALL
static getLogger(string $a_component_id)
Get component logger.
static convert_to_bool(string $string)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getRollupRules(object $iNode, object $ioAct)
static getAuxResources(object $iNode, object $ioAct)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
extractSeqInfo(object $iNode, object $ioAct)
static fillinADLSeqMaps(object $iNode, object $map)
const COMBINATION_ANY
global $DIC
Definition: feed.php:28
static getObjectives(object $iNode, object $ioAct)
$objectives
static getADLSEQObjectives(object $iNode, object $ioAct)
buildNode(object $node, ?object $seq, object $doc)
static getObjectiveMaps(object $iNode)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static extractSeqRuleConditions(object $iNode)
buildNodeSeqTree(string $file)
static lookupElement(object $iNode, ?string $iElement)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getADLSeqMaps(object $iNode, object $curseqobj)
static getSequencingRules(object $iNode, object $ioAct)