ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
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
49require_once("SeqActivity.php");
50
51require_once("SeqRule.php");
52require_once("SeqRuleset.php");
53
54require_once("SeqCondition.php");
55require_once("SeqConditionSet.php");
56
57require_once("SeqObjective.php");
58require_once("SeqObjectiveMap.php");
59
60require_once("SeqRollupRule.php");
61require_once("SeqRollupRuleset.php");
62
63require_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((float)$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
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
const COMBINATION_ALL
const COMBINATION_ANY
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.
$res
Definition: ltiservices.php:69
global $DIC
Definition: shib_login.php:26
$objectives