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