ILIAS  release_8 Revision v8.24
SeqTreeBuilder.php
Go to the documentation of this file.
1<?php
2
3declare(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
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
333 // Look for 'randomizationTiming'
334 $tempVal = $curNode->getAttribute("randomizationTiming");
335 if ($tempVal) {
336 $ioAct->setRandomTiming($tempVal);
337 }
338
339 // Look for 'selectCount'
340 $tempVal = $curNode->getAttribute("selectCount");
341 if ($tempVal) {
342 $ioAct->setSelectCount($tempVal);
343 }
344
345 // Look for 'reorderChildren'
346 $tempVal = $curNode->getAttribute("reorderChildren");
347 if ($tempVal) {
348 $ioAct->setReorderChildren(self::convert_to_bool($tempVal));
349 }
350
351 // Look for 'selectionTiming'
352 $tempVal = $curNode->getAttribute("selectionTiming");
353 if ($tempVal) {
354 $ioAct->setSelectionTiming($tempVal);
355 }
356 } elseif ($curNode->localName === "deliveryControls") {
357
358 // Look for 'tracked'
359 $tempVal = $curNode->getAttribute("tracked");
360 if ($tempVal) {
361 $ioAct->setIsTracked(self::convert_to_bool($tempVal));
362 }
363
364 // Look for 'completionSetByContent'
365 $tempVal = $curNode->getAttribute("completionSetByContent");
366 if ($tempVal) {
367 $ioAct->setSetCompletion(self::convert_to_bool($tempVal));
368 }
369
370 // Look for 'objectiveSetByContent'
371 $tempVal = $curNode->getAttribute("objectiveSetByContent");
372 if ($tempVal) {
373 $ioAct->setSetObjective(self::convert_to_bool($tempVal));
374 }
375 } elseif ($curNode->localName === "constrainedChoiceConsiderations") {
376
377 // Look for 'preventActivation'
378 $tempVal = $curNode->getAttribute("preventActivation");
379 if ($tempVal) {
380 $ioAct->setPreventActivation(self::convert_to_bool($tempVal));
381 }
382
383 // Look for 'constrainChoice'
384 $tempVal = $curNode->getAttribute("constrainChoice");
385 if ($tempVal) {
386 $ioAct->setConstrainChoice(self::convert_to_bool($tempVal));
387 }
388 } elseif ($curNode->localName === "rollupConsiderations") {
389
390 // Look for 'requiredForSatisfied'
391 $tempVal = $curNode->getAttribute("requiredForSatisfied");
392 if ($tempVal) {
393 $ioAct->setRequiredForSatisfied($tempVal);
394 }
395
396 // Look for 'requiredForNotSatisfied'
397 $tempVal = $curNode->getAttribute("requiredForNotSatisfied");
398 if ($tempVal) {
399 $ioAct->setRequiredForNotSatisfied($tempVal);
400 }
401
402 // Look for 'requiredForCompleted'
403 $tempVal = $curNode->getAttribute("requiredForCompleted");
404 if ($tempVal) {
405 $ioAct->setRequiredForCompleted($tempVal);
406 }
407
408 // Look for 'requiredForIncomplete'
409 $tempVal = $curNode->getAttribute("requiredForIncomplete");
410 if ($tempVal) {
411 $ioAct->setRequiredForIncomplete($tempVal);
412 }
413
414 // Look for 'measureSatisfactionIfActive'
415 $tempVal = $curNode->getAttribute("measureSatisfactionIfActive");
416 if ($tempVal) {
417 $ioAct->setSatisfactionIfActive(self::convert_to_bool($tempVal));
418 }
419 }
420 } //end note-type check
421 } //end for-loop
422
423 return $ioAct;
424 }
425
426
427 public static function getObjectives(object $iNode, object $ioAct): object
428 {
429 global $DIC;
430 $ilLog = ilLoggerFactory::getLogger('sc13');
431
432
433 $ok = true;
434 $tempVal = null;
435 $objectives = array();
436 $children = $iNode->childNodes;
437 for ($i = 0; $i < $children->length; $i++) {
438 $curNode = $children->item($i);
439 if ($curNode->nodeType == XML_ELEMENT_NODE) {
440 if ($curNode->localName === "primaryObjective" || $curNode->localName === "objective") {
441 $obj = new SeqObjective();
442 if ($curNode->localName === "primaryObjective") {
443 $obj->mContributesToRollup = true;
444 }
445
446 // Look for 'objectiveID'
447 $tempVal = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("objectiveID")));
448 if ($tempVal) {
449 $obj->mObjID = $tempVal;
450 }
451
452 // Look for 'satisfiedByMeasure'
453 $tempVal = $curNode->getAttribute("satisfiedByMeasure");
454 if ($tempVal) {
455 $obj->mSatisfiedByMeasure = self::convert_to_bool($tempVal);
456 }
457 // Look for 'minNormalizedMeasure'
458 $tempVal = self::lookupElement($curNode, "minNormalizedMeasure");
459 if ($tempVal) {
460 $obj->mMinMeasure = (float) $tempVal;
461 }
462
463 //get ObjectiveMaps
464 $maps = self::getObjectiveMaps($curNode);
465 if ($maps != null) {
466 $obj->mMaps = $maps;
467 }
468 //$obj->mContributesToRollup = true;
469 //add class
470 $c_obj['_SeqObjective'] = $obj;
471 $objectives[] = $c_obj;
472 }
473 }
474 }
475 $ioAct->setObjectives($objectives);
476 return $ioAct;
477 }
478
479 public static function getADLSEQObjectives(object $iNode, object $ioAct): object
480 {
481 global $DIC;
482 $ilLog = ilLoggerFactory::getLogger('sc13');
483 $objectives = $ioAct->mObjectives;
484 $children = $iNode->childNodes;
485 for ($i = 0; $i < $children->length; $i++) {
486 $curNode = $children->item($i);
487 if ($curNode->nodeType == XML_ELEMENT_NODE) {
488 if ($curNode->localName === "objective") {
489 // get the objectiveID
490 $adlseqobjid = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("objectiveID")));
491
492 // find the imsss objective with the same objectiveID
493 $curseqobj = null;
494 foreach ($objectives as $j => $value) {
495 $seqobj = $value['_SeqObjective'];
496 if ($seqobj->mObjID == $adlseqobjid) {
497 $curseqobj = $seqobj;
498 $curseqobjindex = $j;
499 break;
500 }
501 }
502
503 // if there's a current seq then let's add the maps
504 if ($curseqobj != null) {
505 // for each adlseq map info populate that mMaps with map info in the adlseq objective
506 $curseqobj = self::getADLSeqMaps($curNode, $curseqobj);
507 $seqobj = $curseqobj;
508 $objectives[$curseqobjindex]['_SeqObjective'] = $seqobj;
509 }
510 }
511 }
512 }
513 // before i leave what do i have to duplicate in SeqActivity or some other class?
514 // prolly just
515 $ioAct->setObjectives($objectives);
516 return $ioAct;
517 }
518
519 public static function getADLSeqMaps(object $iNode, object $curseqobj): object
520 {
521 if (count($curseqobj->mMaps) == null) {
522 $curseqobj->mMaps = array();
523 }
524 $maps = $curseqobj->mMaps;
525
526 $children = $iNode->childNodes;
527 for ($i = 0; $i < $children->length; $i++) {
528 $curNode = $children->item($i);
529 if ($curNode->nodeType == XML_ELEMENT_NODE) {
530 if ($curNode->localName === "mapInfo") {
531 $map = new SeqObjectiveMap();
532 $curadltargetobjid = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("targetObjectiveID")));
533 // if the adl map target id matches an imsssssss one, then add to the imsssss one
534 $matchingmapindex = -1;
535 foreach ($maps as $j => $value) {
536 if ($value['_SeqObjectiveMap']->mGlobalObjID == $curadltargetobjid) {
537 $map = $value['_SeqObjectiveMap'];
538 $matchingmapindex = $j;
539 }
540 }
541 // tom: if default access is dependent on map existence then this will need to know if an imsss:mapInfo existed
542 $map = self::fillinADLSeqMaps($curNode, $map);
543
544 if ($matchingmapindex > -1) {
545 $c_map['_SeqObjectiveMap'] = $map;
546 $maps[$matchingmapindex] = $c_map;
547 } else {
548 $c_map['_SeqObjectiveMap'] = $map;
549 $maps[] = $c_map;
550 }
551 }
552 }
553 }
554 $curseqobj->mMaps = $maps;
555 return $curseqobj;
556 }
557
558 public static function fillinADLSeqMaps(object $iNode, object $map): object
559 {
560 if ($map->mGlobalObjID == null) {
561 $map->mGlobalObjID = preg_replace('/(%20)+/', ' ', trim($iNode->getAttribute("targetObjectiveID")));
562 }
563
564 $tempVal = $iNode->getAttribute("readRawScore");
565 if ($tempVal) {
566 $map->mReadRawScore = self::convert_to_bool($tempVal);
567 }
568
569 $tempVal = $iNode->getAttribute("readMinScore");
570 if ($tempVal) {
571 $map->mReadMinScore = self::convert_to_bool($tempVal);
572 }
573
574 $tempVal = $iNode->getAttribute("readMaxScore");
575 if ($tempVal) {
576 $map->mReadMaxScore = self::convert_to_bool($tempVal);
577 }
578
579 $tempVal = $iNode->getAttribute("readCompletionStatus");
580 if ($tempVal) {
581 $map->mReadCompletionStatus = self::convert_to_bool($tempVal);
582 }
583
584 $tempVal = $iNode->getAttribute("readProgressMeasure");
585 if ($tempVal) {
586 $map->mReadProgressMeasure = self::convert_to_bool($tempVal);
587 }
588
589 $tempVal = $iNode->getAttribute("writeRawScore");
590 if ($tempVal) {
591 $map->mWriteRawScore = self::convert_to_bool($tempVal);
592 }
593
594 $tempVal = $iNode->getAttribute("writeMinScore");
595 if ($tempVal) {
596 $map->mWriteMinScore = self::convert_to_bool($tempVal);
597 }
598
599 $tempVal = $iNode->getAttribute("writeMaxScore");
600 if ($tempVal) {
601 $map->mWriteMaxScore = self::convert_to_bool($tempVal);
602 }
603
604 $tempVal = $iNode->getAttribute("writeCompletionStatus");
605 if ($tempVal) {
606 $map->mWriteCompletionStatus = self::convert_to_bool($tempVal);
607 }
608
609 $tempVal = $iNode->getAttribute("writeProgressMeasure");
610 if ($tempVal) {
611 $map->mWriteProgressMeasure = self::convert_to_bool($tempVal);
612 }
613
614 return $map;
615 }
616
617 public static function getObjectiveMaps(object $iNode): ?array
618 {
619 $tempVal = null;
620 $maps = array();
621 $children = $iNode->childNodes;
622 for ($i = 0; $i < $children->length; $i++) {
623 $curNode = $children->item($i);
624 if ($curNode->nodeType == XML_ELEMENT_NODE) {
625 if ($curNode->localName === "mapInfo") {
626 $map = new SeqObjectiveMap();
627
628 // Look for 'targetObjectiveID'
629 $tempVal = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("targetObjectiveID")));
630 if ($tempVal) {
631 $map->mGlobalObjID = $tempVal;
632 }
633
634 // Look for 'readSatisfiedStatus'
635 $tempVal = $curNode->getAttribute("readSatisfiedStatus");
636 if ($tempVal) {
637 $map->mReadStatus = self::convert_to_bool($tempVal);
638 }
639
640 // Look for 'readNormalizedMeasure'
641 $tempVal = $curNode->getAttribute("readNormalizedMeasure");
642 if ($tempVal) {
643 $map->mReadMeasure = self::convert_to_bool($tempVal);
644 }
645
646 // Look for 'writeSatisfiedStatus'
647 $tempVal = $curNode->getAttribute("writeSatisfiedStatus");
648 if ($tempVal) {
649 $map->mWriteStatus = self::convert_to_bool($tempVal);
650 }
651
652 // Look for 'writeNormalizedMeasure'
653 $tempVal = $curNode->getAttribute("writeNormalizedMeasure");
654 if ($tempVal) {
655 $map->mWriteMeasure = self::convert_to_bool($tempVal);
656 }
657 //add class
658 $c_map['_SeqObjectiveMap'] = $map;
659 $maps[] = $c_map;
660 }
661 }
662 }
663 if (count($maps) == null) {
664 $maps = null;
665 }
666 return $maps;
667 }
668
669 public static function getRollupRules(object $iNode, object $ioAct): object
670 {
671 $ok = true;
672 $tempVal = null;
673 $rollupRules = array();
674
675 // Look for 'rollupObjectiveSatisfied'
676 $tempVal = $iNode->getAttribute("rollupObjectiveSatisfied");
677 if ($tempVal) {
678 $ioAct->setIsObjRolledUp(self::convert_to_bool($tempVal));
679 }
680
681 // Look for 'objectiveMeasureWeight'
682 $tempVal = $iNode->getAttribute("objectiveMeasureWeight");
683 if ($tempVal) {
684 $ioAct->setObjMeasureWeight($tempVal);
685 }
686 // Look for 'rollupProgressCompletion'
687 $tempVal = $iNode->getAttribute("rollupProgressCompletion");
688 if ($tempVal) {
689 $ioAct->setIsProgressRolledUp(self::convert_to_bool($tempVal));
690 }
691 $children = $iNode->childNodes;
692 for ($i = 0; $i < $children->length; $i++) {
693 $curNode = $children->item($i);
694 if ($curNode->nodeType == XML_ELEMENT_NODE) {
695 if ($curNode->localName === "rollupRule") {
696 $rule = new SeqRollupRule();
697
698 // Look for 'childActivitySet'
699 $tempVal = $curNode->getAttribute("childActivitySet");
700 if ($tempVal) {
701 $rule->mChildActivitySet = $tempVal;
702 }
703 // Look for 'minimumCount'
704 $tempVal = $curNode->getAttribute("minimumCount");
705 if ($tempVal) {
706 $rule->mMinCount = $tempVal;
707 }
708
709 // Look for 'minimumPercent'
710 $tempVal = $curNode->getAttribute("minimumPercent");
711 if ($tempVal) {
712 $rule->mMinPercent = $tempVal;
713 }
714 $rule->mConditions['_SeqConditionSet'] = new SeqConditionSet(true);
715 $conditions = array();
716 $ruleInfo = $curNode->childNodes;
717 for ($j = 0; $j < $ruleInfo->length; $j++) {
718 $curRule = $ruleInfo->item($j);
719 //check for element
720 if ($curRule->nodeType == XML_ELEMENT_NODE) {
721 if ($curRule->localName === "rollupConditions") {
722 $tempVal = $curRule->getAttribute("conditionCombination");
723 if ($tempVal) {
724 $rule->mConditions['_SeqConditionSet']->mCombination = $tempVal;
725 } else {
726 $rule->mConditions['_SeqConditionSet']->mCombination = COMBINATION_ANY;
727 }
728 $conds = $curRule->childNodes;
729 for ($k = 0; $k < $conds->length; $k++) {
730 $con = $conds->item($k);
731 if ($con->nodeType == XML_ELEMENT_NODE) {
732 if ($con->localName === "rollupCondition") {
733 $cond = new SeqCondition();
734 // Look for 'condition'
735 $tempVal = $con->getAttribute("condition");
736 if ($tempVal) {
737 $cond->mCondition = $tempVal;
738 }
739 // Look for 'operator'
740 $tempVal = $con->getAttribute("operator");
741 if ($tempVal) {
742 if ($tempVal === 'not') {
743 $cond->mNot = true;
744 } else {
745 $cond->mNot = false;
746 }
747 }
748 //add class
749 $c_cond['_SeqCondition'] = $cond;
750 $conditions[] = $c_cond;
751 }
752 }
753 }
754 } elseif ($curRule->localName === "rollupAction") {
755 $tempVal = $curRule->getAttribute("action");
756 if ($tempVal) {
757 $rule->setRollupAction($tempVal);
758 }
759 }
760 }
761 }
762 // Add the conditions to the condition set for the rule
763 $rule->mConditions['_SeqConditionSet']->mConditions = $conditions;
764
765 // Add the rule to the ruleset
766 //add class
767 $c_rule['_SeqRollupRule'] = $rule;
768 $rollupRules[] = $c_rule;
769 }
770 }
771 }
772
773 if ($rollupRules != null) {
774 $rules = new SeqRollupRuleset($rollupRules);
775 // Set the Activity's rollup rules
776 //add class
777 $c_rules['_SeqRollupRuleset'] = $rules;
778 $ioAct->setRollupRules($c_rules);
779 }
780
781 return $ioAct;
782 }
783
784
785 public static function getSequencingRules(object $iNode, object $ioAct): object
786 {
787 //local variables
788 $ok = true;
789 $tempVal = null;
790
791 $preRules = array();
792 $exitRules = array();
793 $postRules = array();
794
795 //get children
796 $children = $iNode->childNodes;
797
798 //find sequencing rules
799 for ($i = 0; $i < $children->length; $i++) {
800 $curNode = $children->item($i);
801 if ($curNode->nodeType == XML_ELEMENT_NODE) {
802 if ($curNode->localName === "preConditionRule" || $curNode->localName === "exitConditionRule" || $curNode->localName === "postConditionRule") {
803 $rule = new SeqRule();
804 $ruleInfo = $curNode->childNodes;
805 for ($j = 0; $j < $ruleInfo->length; $j++) {
806 $curRule = $ruleInfo->item($j);
807 //echo "$curRule->localName\n";
808 if ($curRule->nodeType == XML_ELEMENT_NODE) {
809 if ($curRule->localName === "ruleConditions") {
810 $rule->mConditions = self::extractSeqRuleConditions($curRule);
811 } elseif ($curRule->localName === "ruleAction") {
812 $tempVal = $curRule->getAttribute("action");
813 if ($tempVal) {
814 $rule->mAction = $tempVal;
815 }
816 }
817 }
818 }//end for inner
819 if ($rule->mConditions != null && $rule->mAction != null) {
820 //changed from ADL Code..
821 if ($curNode->localName === "preConditionRule") {
822 //echo "ADD PRE";
823 //add class
824 $c_rule['_SeqRule'] = $rule;
825 $preRules[] = $c_rule;
826 }
827 if ($curNode->localName === "exitConditionRule") {
828 //echo "ADD EXIT";
829 //add class
830 $c_rule['_SeqRule'] = $rule;
831 $exitRules[] = $c_rule;
832 }
833 if ($curNode->localName === "postConditionRule") {
834 //echo "ADD POST";
835 //add class
836 $c_rule['_SeqRule'] = $rule;
837 $postRules[] = $c_rule;
838 }
839 }
840 } //end if preCondition
841 } //end if ELEMENT
842 }
843
844 if (count($preRules) > 0) {
845 $rules = new SeqRuleset($preRules);
846 //add class
847 $c_rules['_SeqRuleset'] = $rules;
848 $ioAct->setPreSeqRules($c_rules);
849 }
850
851 if (count($exitRules) > 0) {
852 $rules = new SeqRuleset($exitRules);
853 //add class
854 $c_rules['_SeqRuleset'] = $rules;
855 $ioAct->setExitSeqRules($c_rules);
856 }
857 if (count($postRules) > 0) {
858 $rules = new SeqRuleset($postRules);
859 //add class
860 $c_rules['_SeqRuleset'] = $rules;
861 $ioAct->setPostSeqRules($c_rules);
862 }
863 //echo json_encode($ioAct);
864
865 return $ioAct;
866 }
867
868 public static function extractSeqRuleConditions(object $iNode): array
869 {
870 $tempVal = null;
871 $condSet = new SeqConditionSet(false);
872
873 $conditions = array();
874 $tempVal = $iNode->getAttribute("conditionCombination");
875 if ($tempVal) {
876 $condSet->mCombination = $tempVal;
877 } else {
878 $condSet->mCombination = COMBINATION_ALL;
879 }
880 $condInfo = $iNode->childNodes;
881 for ($i = 0; $i < $condInfo->length; $i++) {
882 $curCond = $condInfo->item($i);
883 if ($curCond->nodeType == XML_ELEMENT_NODE) {
884 if ($curCond->localName === "ruleCondition") {
885 $cond = new SeqCondition();
886
887 //look for condition
888 $tempVal = $curCond->getAttribute("condition");
889 if ($tempVal) {
890 $cond->mCondition = $tempVal;
891 }
892
893 // Look for 'referencedObjective'
894 $tempVal = preg_replace('/(%20)+/', ' ', trim($curCond->getAttribute("referencedObjective")));
895 if ($tempVal) {
896 $cond->mObjID = $tempVal;
897 }
898
899 // Look for 'measureThreshold'
900 $tempVal = $curCond->getAttribute("measureThreshold");
901 if ($tempVal) {
902 $cond->mThreshold = $tempVal;
903 }
904
905 // Look for 'operator'
906 $tempVal = $curCond->getAttribute("operator");
907 if ($tempVal) {
908 if ($tempVal === 'not') {
909 $cond->mNot = true;
910 } else {
911 $cond->mNot = false;
912 }
913 }
914
915 //add class
916 $c_cond['_SeqCondition'] = $cond;
917 $conditions[] = $c_cond;
918 }
919 }
920 }
921
922 if (count($conditions) > 0) {
923 $condSet->mConditions = $conditions;
924 } else {
925 $condSet->mConditions = null;
926 }
927 //add class
928 $c_condSet['_SeqConditionSet'] = $condSet;
929 return $c_condSet;
930 }
931
932 public static function getAuxResources(object $iNode, object $ioAct): object
933 {
934 $ok = true;
935 $tempVal = null;
936 $auxRes = array();
937 //get children
938 $children = $iNode->childNodes;
939
940 //find ressources
941 for ($i = 0; $i < $children->length; $i++) {
942 $curNode = $children->item($i);
943 if ($curNode->nodeType == XML_ELEMENT_NODE) {
944 if ($curNode->localName === "auxiliaryResource") {
945 //found it
947
948 // Get the resource's purpose
949 $tempVal = $curNode->getAttribute("purpose");
950 if ($tempVal) {
951 $res->mType = $tempVal;
952 }
953 // Get the resource's ID
954 $tempVal = preg_replace('/(%20)+/', ' ', trim($curNode->getAttribute("auxiliaryResourceID")));
955 if ($tempVal) {
956 $res->mResourceID = $tempVal;
957 }
958 $auxRes[] = $res;
959 }
960 }
961 }
962 //add class
963 $c_auxRes['_ADLAuxiliaryResource'] = $auxRes;
964 $ioAct->setAuxResources($c_auxRes);
965 return $ioAct;
966 }
967
968 //helper functions
969
970 private static function convert_to_bool(string $string): bool
971 {
972 return strtoupper($string) !== "FALSE";
973 }
974
975
976 private static function lookupElement(object $iNode, ?string $iElement): ?string
977 {
978 $value = null;
979 $curNode = null;
980 $children = null;
981
982 if ($iNode != null && $iElement != null) {
983 $children = $iNode->childNodes;
984 for ($i = 0; $i < $children->length; $i++) {
985 $curNode = $children->item($i);
986 if (($curNode->nodeType == XML_ELEMENT_NODE)) {
987 if ($curNode->localName == $iElement) {
988 break;
989 }
990 }
991 }
992 if ($curNode != null) {
993 $comp = $curNode->localName;
994 if ($comp != null) {
995 if ($comp != $iElement) {
996 $curNode = null;
997 }
998 } else {
999 $curNode = null;
1000 }
1001 }
1002 } else {
1003 //$iElement is null
1004 $curNode = $iNode;
1005 }
1006
1007 if ($curNode != null) {
1008 $children = $curNode->childNodes;
1009 if ($children != null) {
1010 for ($i = 0; $i < $children->length; $i++) {
1011 $curNode = $children->item($i);
1012 // make sure we have a 'text' element
1013 if (($curNode->nodeType == XML_TEXT_NODE) || ($curNode->nodeType == XML_CDATA_SECTION_NODE)) {
1014 $value = $value . $curNode->nodeValue;
1015 }
1016 }
1017 }
1018 }
1019 return $value;
1020 }
1021 } //end class
const COMBINATION_ALL
const COMBINATION_ANY
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...
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...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getADLSEQObjectives(object $iNode, object $ioAct)
static getAuxResources(object $iNode, object $ioAct)
extractSeqInfo(object $iNode, object $ioAct)
static getADLSeqMaps(object $iNode, object $curseqobj)
buildNode(object $node, ?object $seq, object $doc)
static getObjectiveMaps(object $iNode)
static getSequencingRules(object $iNode, object $ioAct)
static lookupElement(object $iNode, ?string $iElement)
static convert_to_bool(string $string)
static getRollupRules(object $iNode, object $ioAct)
static getObjectives(object $iNode, object $ioAct)
static extractSeqRuleConditions(object $iNode)
static fillinADLSeqMaps(object $iNode, object $map)
buildNodeSeqTree(string $file)
static getLogger(string $a_component_id)
Get component logger.
global $DIC
Definition: feed.php:28
$res
Definition: ltiservices.php:69
$i
Definition: metadata.php:41
$objectives