[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 function scorm_seq_exit_action_rules($seq, $userid) { 18 $sco = $seq->currentactivity; 19 $ancestors = scorm_get_ancestors($sco); 20 $exittarget = null; 21 foreach (array_reverse($ancestors) as $ancestor) { 22 if (scorm_seq_rules_check($ancestor, 'exit') != null) { 23 $exittarget = $ancestor; 24 break; 25 } 26 } 27 if ($exittarget != null) { 28 $commons = array_slice($ancestors, 0, scorm_find_common_ancestor($ancestors, $exittarget)); 29 30 // Terminate Descendent Attempts Process. 31 if ($commons) { 32 foreach ($commons as $ancestor) { 33 scorm_seq_end_attempt($ancestor, $userid, $seq->attempt); 34 $seq->currentactivity = $ancestor; 35 } 36 } 37 } 38 return $seq; 39 } 40 41 function scorm_seq_post_cond_rules($seq, $userid) { 42 $sco = $seq->currentactivity; 43 if (!$seq->suspended) { 44 if ($action = scorm_seq_rules_check($sco, 'post') != null) { 45 switch($action) { 46 case 'retry': 47 case 'continue': 48 case 'previous': 49 $seq->sequencing = $action; 50 break; 51 case 'exitparent': 52 case 'exitall': 53 $seq->termination = $action; 54 break; 55 case 'retryall': 56 $seq->termination = 'exitall'; 57 $seq->sequencing = 'retry'; 58 break; 59 } 60 } 61 } 62 return $seq; 63 } 64 65 66 function scorm_seq_evaluate_rollupcond($sco, $conditioncombination, $rollupruleconds, $userid) { 67 $bag = Array(); 68 $con = ""; 69 $val = false; 70 $unk = false; 71 foreach ($rollupruleconds as $rolluprulecond) { 72 $condit = scorm_evaluate_condition($rolluprulecond, $sco, $userid); 73 if ($rolluprulecond->operator == 'not') { // If operator is not, negate the condition. 74 if ($rolluprulecond->cond != 'unknown') { 75 if ($condit) { 76 $condit = false; 77 } else { 78 $condit = true; 79 } 80 } else { 81 $condit = 'unknown'; 82 } 83 array_push($childrenbag, $condit); 84 } 85 } 86 if (empty($bag)) { 87 return 'unknown'; 88 } else { 89 $i = 0; 90 foreach ($bag as $b) { 91 if ($rolluprulecond->conditioncombination == 'all') { 92 $val = true; 93 if ($b == 'unknown') { 94 $unk = true; 95 } 96 if ($b === false) { 97 return false; 98 } 99 } else { 100 $val = false; 101 102 if ($b == 'unknown') { 103 $unk = true; 104 } 105 if ($b === true) { 106 return true; 107 } 108 } 109 } 110 } 111 if ($unk) { 112 return 'unknown'; 113 } 114 return $val; 115 } 116 117 function scorm_seq_check_child ($sco, $action, $userid) { 118 global $DB; 119 120 $included = false; 121 $sco = scorm_get_sco($sco->id); 122 $r = $DB->get_record('scorm_scoes_track', array('scoid' => $sco->id, 'userid' => $userid, 'element' => 'activityattemptcount')); 123 if ($action == 'satisfied' || $action == 'notsatisfied') { 124 if (!$sco->rollupobjectivesatisfied) { 125 $included = true; 126 if (($action == 'satisfied' && $sco->requiredforsatisfied == 'ifnotsuspended') || 127 ($action == 'notsatisfied' && $sco->requiredfornotsatisfied == 'ifnotsuspended')) { 128 129 if (!scorm_seq_is('activityprogressstatus', $sco->id, $userid) || 130 ((($r->value) > 0) && !scorm_seq_is('suspended', $sco->id, $userid))) { 131 $included = false; 132 } 133 134 } else { 135 if (($action == 'satisfied' && $sco->requiredforsatisfied == 'ifattempted') || 136 ($action == 'notsatisfied' && $sco->requiredfornotsatisfied == 'ifattempted')) { 137 if (!scorm_seq_is('activityprogressstatus', $sco->id, $userid) || (($r->value) == 0)) { 138 $included = false; 139 } 140 } else { 141 if (($action == 'satisfied' && $sco->requiredforsatisfied == 'ifnotskipped') || 142 ($action == 'notsatisfied' && $sco->requiredfornotsatisfied == 'ifnotskipped')) { 143 $rulch = scorm_seq_rules_check($sco, 'skip'); 144 if ($rulch != null) { 145 $included = false; 146 } 147 } 148 } 149 } 150 } 151 } 152 if ($action == 'completed' || $action == 'incomplete') { 153 if (!$sco->rollupprogresscompletion) { 154 $included = true; 155 156 if (($action == 'completed' && $sco->requiredforcompleted == 'ifnotsuspended') || 157 ($action == 'incomplete' && $sco->requiredforincomplete == 'ifnotsuspended')) { 158 159 if (!scorm_seq_is('activityprogressstatus', $sco->id, $userid) || 160 ((($r->value) > 0)&& !scorm_seq_is('suspended', $sco->id, $userid))) { 161 $included = false; 162 } 163 164 } else { 165 166 if (($action == 'completed' && $sco->requiredforcompleted == 'ifattempted') || 167 ($action == 'incomplete' && $sco->requiredforincomplete == 'ifattempted')) { 168 if (!scorm_seq_is('activityprogressstatus', $sco->id, $userid) || (($r->value) == 0)) { 169 $included = false; 170 } 171 172 } else { 173 if (($action == 'completed' && $sco->requiredforsatisfied == 'ifnotskipped') || 174 ($action == 'incomplete' && $sco->requiredfornotsatisfied == 'ifnotskipped')) { 175 $rulch = scorm_seq_rules_check($sco, 'skip'); 176 if ($rulch != null) { 177 $included = false; 178 } 179 } 180 } 181 } 182 } 183 } 184 return $included; 185 } 186 187 function scorm_seq_sequencing ($scoid, $userid, $seq) { 188 189 switch ($seq->sequencing) { 190 case 'start': 191 // We'll see the parameters we have to send, this should update delivery and end. 192 $seq = scorm_seq_start_sequencing($scoid, $userid, $seq); 193 $seq->sequencing = true; 194 break; 195 196 case 'resumeall': 197 // We'll see the parameters we have to send, this should update delivery and end. 198 $seq = scorm_seq_resume_all_sequencing($scoid, $userid, $seq); 199 $seq->sequencing = true; 200 break; 201 202 case 'exit': 203 // We'll see the parameters we have to send, this should update delivery and end. 204 $seq = scorm_seq_exit_sequencing($scoid, $userid, $seq); 205 $seq->sequencing = true; 206 break; 207 208 case 'retry': 209 // We'll see the parameters we have to send, this should update delivery and end. 210 $seq = scorm_seq_retry_sequencing($scoid, $userid, $seq); 211 $seq->sequencing = true; 212 break; 213 214 case 'previous': 215 // We'll see the parameters we have to send, this should update delivery and end. 216 $seq = scorm_seq_previous_sequencing($scoid, $userid, $seq); 217 $seq->sequencing = true; 218 break; 219 220 case 'choice': 221 // We'll see the parameters we have to send, this should update delivery and end. 222 $seq = scorm_seq_choice_sequencing($scoid, $userid, $seq); 223 $seq->sequencing = true; 224 break; 225 } 226 227 if ($seq->exception != null) { 228 $seq->sequencing = false; 229 return $seq; 230 } 231 232 $seq->sequencing = true; 233 return $seq; 234 } 235 236 function scorm_seq_start_sequencing($scoid, $userid, $seq) { 237 global $DB; 238 239 if (!empty($seq->currentactivity)) { 240 $seq->delivery = null; 241 $seq->exception = 'SB.2.5-1'; 242 return $seq; 243 } 244 $sco = $DB->get_record('scorm_scoes', array('scoid' => $scoid, 'userid' => $userid)); 245 if (($sco->parent == '/') && scorm_is_leaf($sco)) { // If the activity is the root and is leaf. 246 $seq->delivery = $sco; 247 } else { 248 $ancestors = scorm_get_ancestors($sco); 249 $ancestorsroot = array_reverse($ancestors); 250 $res = scorm_seq_flow($ancestorsroot[0], 'forward', $seq, true, $userid); 251 if ($res) { 252 return $res; 253 } 254 } 255 } 256 257 function scorm_seq_resume_all_sequencing($scoid, $userid, $seq) { 258 global $DB; 259 260 if (!empty($seq->currentactivity)) { 261 $seq->delivery = null; 262 $seq->exception = 'SB.2.6-1'; 263 return $seq; 264 } 265 $track = $DB->get_record('scorm_scoes_track', array('scoid' => $scoid, 'userid' => $userid, 'element' => 'suspendedactivity')); 266 if (!$track) { 267 $seq->delivery = null; 268 $seq->exception = 'SB.2.6-2'; 269 return $seq; 270 } 271 // We assign the sco to the delivery. 272 $seq->delivery = $DB->get_record('scorm_scoes', array('scoid' => $scoid, 'userid' => $userid)); 273 } 274 275 function scorm_seq_continue_sequencing($scoid, $userid, $seq) { 276 if (empty($seq->currentactivity)) { 277 $seq->delivery = null; 278 $seq->exception = 'SB.2.7-1'; 279 return $seq; 280 } 281 $currentact = $seq->currentactivity; 282 if ($currentact->parent != '/') { 283 // If the activity is the root and is leaf. 284 $parent = scorm_get_parent ($currentact); 285 286 if (!isset($parent->flow) || ($parent->flow == false)) { 287 $seq->delivery = null; 288 $seq->exception = 'SB.2.7-2'; 289 return $seq; 290 } 291 292 $res = scorm_seq_flow($currentact, 'forward', $seq, false, $userid); 293 if ($res) { 294 return $res; 295 } 296 } 297 } 298 299 function scorm_seq_previous_sequencing($scoid, $userid, $seq) { 300 if (empty($seq->currentactivity)) { 301 $seq->delivery = null; 302 $seq->exception = 'SB.2.8-1'; 303 return $seq; 304 } 305 306 $currentact = $seq->currentactivity; 307 if ($currentact->parent != '/') { // If the activity is the root and is leaf. 308 $parent = scorm_get_parent ($currentact); 309 if (!isset($parent->flow) || ($parent->flow == false)) { 310 $seq->delivery = null; 311 $seq->exception = 'SB.2.8-2'; 312 return $seq; 313 } 314 315 $res = scorm_seq_flow($currentact, 'backward', $seq, false, $userid); 316 if ($res) { 317 return $res; 318 } 319 } 320 } 321 322 function scorm_seq_exit_sequencing($scoid, $userid, $seq) { 323 if (empty($seq->currentactivity)) { 324 $seq->delivery = null; 325 $seq->exception = 'SB.2.11-1'; 326 return $seq; 327 } 328 329 if ($seq->active) { 330 $seq->endsession = false; 331 $seq->exception = 'SB.2.11-2'; 332 return $seq; 333 } 334 $currentact = $seq->currentactivity; 335 if ($currentact->parent == '/') { 336 $seq->endsession = true; 337 return $seq; 338 } 339 340 $seq->endsession = false; 341 return $seq; 342 } 343 344 function scorm_seq_retry_sequencing($scoid, $userid, $seq) { 345 if (empty($seq->currentactivity)) { 346 $seq->delivery = null; 347 $seq->exception = 'SB.2.10-1'; 348 return $seq; 349 } 350 if ($seq->active || $seq->suspended) { 351 $seq->delivery = null; 352 $seq->exception = 'SB.2.10-2'; 353 return $seq; 354 } 355 356 if (!scorm_is_leaf($seq->currentactivity)) { 357 $res = scorm_seq_flow($seq->currentactivity, 'forward', $seq, true, $userid); 358 if ($res != null) { 359 return $res; 360 } else { 361 // Return deliver. 362 $seq->delivery = null; 363 $seq->exception = 'SB.2.10-3'; 364 return $seq; 365 } 366 } else { 367 $seq->delivery = $seq->currentactivity; 368 return $seq; 369 } 370 371 } 372 373 function scorm_seq_choice_sequencing($sco, $userid, $seq) { 374 375 $avchildren = Array (); 376 $comancestor = null; 377 $traverse = null; 378 379 if ($sco == null) { 380 $seq->delivery = null; 381 $seq->exception = 'SB.2.9-1'; 382 return $seq; 383 } 384 385 $ancestors = scorm_get_ancestors($sco); 386 $arrpath = array_reverse($ancestors); 387 array_push ($arrpath, $sco); // Path from the root to the target. 388 389 foreach ($arrpath as $activity) { 390 if ($activity->parent != '/') { 391 $avchildren = scorm_get_available_children (scorm_get_parent($activity)); 392 $position = array_search($avchildren, $activity); 393 if ($position !== false) { 394 $seq->delivery = null; 395 $seq->exception = 'SB.2.9-2'; 396 return $seq; 397 } 398 } 399 400 if (scorm_seq_rules_check($activity, 'hidefromchoice' != null)) { 401 $seq->delivery = null; 402 $seq->exception = 'SB.2.9-3'; 403 return $seq; 404 } 405 } 406 407 if ($sco->parent != '/') { 408 $parent = scorm_sco_get_parent ($sco); 409 if ( isset($parent->choice) && ($parent->choice == false)) { 410 $seq->delivery = null; 411 $seq->exception = 'SB.2.9-4'; 412 return $seq; 413 } 414 } 415 416 if ($seq->currentactivity != null) { 417 $commonpos = scorm_find_common_ancestor($ancestors, $seq->currentactivity); 418 $comancestor = $arrpath [$commonpos]; 419 } else { 420 $comancestor = $arrpath [0]; 421 } 422 423 if ($seq->currentactivity === $sco) { 424 break; 425 } 426 427 $sib = scorm_get_siblings($seq->currentactivity); 428 $pos = array_search($sib, $sco); 429 430 if ($pos !== false) { 431 $siblings = array_slice($sib, 0, $pos - 1); 432 if (empty($siblings)) { 433 $seq->delivery = null; 434 $seq->exception = 'SB.2.9-5'; 435 return $seq; 436 } 437 438 $children = scorm_get_children (scorm_get_parent ($sco)); 439 $pos1 = array_search($children, $sco); 440 $pos2 = array_search($seq->currentactivity, $sco); 441 if ($pos1 > $pos2) { 442 $traverse = 'forward'; 443 } else { 444 $traverse = 'backward'; 445 } 446 447 foreach ($siblings as $sibling) { 448 $seq = scorm_seq_choice_activity_traversal($sibling, $userid, $seq, $traverse); 449 if (!$seq->reachable) { 450 $seq->delivery = null; 451 return $seq; 452 } 453 } 454 break; 455 } 456 457 if ($seq->currentactivity == null || $seq->currentactivity == $comancestor) { 458 $commonpos = scorm_find_common_ancestor($ancestors, $seq->currentactivity); 459 // Path from the common ancestor to the target activity. 460 $comtarget = array_slice($ancestors, 1, $commonpos - 1); 461 $comtarget = array_reverse($comtarget); 462 463 if (empty($comtarget)) { 464 $seq->delivery = null; 465 $seq->exception = 'SB.2.9-5'; 466 return $seq; 467 } 468 foreach ($comtarget as $act) { 469 $seq = scorm_seq_choice_activity_traversal($act, $userid, $seq, 'forward'); 470 if (!$seq->reachable) { 471 $seq->delivery = null; 472 return $seq; 473 } 474 $act = scorm_get_sco ($acti->id); 475 if (scorm_seq_is('active', $act->id, $userid) && ($act->id != $comancestor->id && $act->preventactivation)) { 476 $seq->delivery = null; 477 $seq->exception = 'SB.2.9-6'; 478 return $seq; 479 } 480 } 481 break; 482 } 483 484 if ($comancestor->id == $sco->id) { 485 486 $ancestorscurrent = scorm_get_ancestors($seq->currentactivity); 487 $possco = array_search($ancestorscurrent, $sco); 488 // Path from the current activity to the target. 489 $curtarget = array_slice($ancestorscurrent, 0, $possco); 490 491 if (empty($curtarget)) { 492 $seq->delivery = null; 493 $seq->exception = 'SB.2.9-5'; 494 return $seq; 495 } 496 $i = 0; 497 foreach ($curtarget as $activ) { 498 $i++; 499 if ($i != count($curtarget)) { 500 if (isset($activ->choiceexit) && ($activ->choiceexit == false)) { 501 $seq->delivery = null; 502 $seq->exception = 'SB.2.9-7'; 503 return $seq; 504 } 505 } 506 } 507 break; 508 } 509 510 if (array_search($ancestors, $comancestor) !== false) { 511 $ancestorscurrent = scorm_get_ancestors($seq->currentactivity); 512 $commonpos = scorm_find_common_ancestor($ancestors, $sco); 513 $curcommon = array_slice($ancestorscurrent, 0, $commonpos - 1); 514 if (empty($curcommon)) { 515 $seq->delivery = null; 516 $seq->exception = 'SB.2.9-5'; 517 return $seq; 518 } 519 520 $constrained = null; 521 foreach ($curcommon as $acti) { 522 $acti = scorm_get_sco($acti->id); 523 if (isset($acti->choiceexit) && ($acti->choiceexit == false)) { 524 $seq->delivery = null; 525 $seq->exception = 'SB.2.9-7'; 526 return $seq; 527 } 528 if ($constrained == null) { 529 if ($acti->constrainchoice == true) { 530 $constrained = $acti; 531 } 532 } 533 } 534 if ($constrained != null) { 535 $fwdir = scorm_get_preorder($constrained); 536 537 if (array_search($fwdir, $sco) !== false) { 538 $traverse = 'forward'; 539 } else { 540 $traverse = 'backward'; 541 } 542 $seq = scorm_seq_choice_flow($constrained, $traverse, $seq); 543 $actconsider = $seq->identifiedactivity; 544 $avdescendents = Array(); 545 $avdescendents = scorm_get_available_descendents($actconsider); 546 if (array_search ($avdescendents, $sco) !== false && $sco->id != $actconsider->id && $constrained->id != $sco->id ) { 547 $seq->delivery = null; 548 $seq->exception = 'SB.2.9-8'; 549 return $seq; 550 } 551 // CONTINUE 11.5.5 ! 552 } 553 554 $commonpos = scorm_find_common_ancestor($ancestors, $seq->currentactivity); 555 $comtarget = array_slice($ancestors, 1, $commonpos - 1);// Path from the common ancestor to the target activity. 556 $comtarget = array_reverse($comtarget); 557 558 if (empty($comtarget)) { 559 $seq->delivery = null; 560 $seq->exception = 'SB.2.9-5'; 561 return $seq; 562 } 563 564 $fwdir = scorm_get_preorder($seq->currentactivity); 565 566 if (array_search($fwdir, $sco) !== false) { 567 foreach ($comtarget as $act) { 568 $seq = scorm_seq_choice_activity_traversal($act, $userid, $seq, 'forward'); 569 if (!$seq->reachable) { 570 $seq->delivery = null; 571 return $seq; 572 } 573 $act = scorm_get_sco($act->id); 574 if (scorm_seq_is('active', $act->id, $userid) && ($act->id != $comancestor->id && 575 ($act->preventactivation == true))) { 576 $seq->delivery = null; 577 $seq->exception = 'SB.2.9-6'; 578 return $seq; 579 } 580 } 581 582 } else { 583 foreach ($comtarget as $act) { 584 $act = scorm_get_sco($act->id); 585 if (scorm_seq_is('active', $act->id, $userid) && $act->id != $comancestor->id && $act->preventactivation == true) { 586 $seq->delivery = null; 587 $seq->exception = 'SB.2.9-6'; 588 return $seq; 589 } 590 } 591 } 592 break; 593 } 594 595 if (scorm_is_leaf ($sco)) { 596 $seq->delivery = $sco; 597 $seq->exception = 'SB.2.9-6'; 598 return $seq; 599 } 600 601 $seq = scorm_seq_flow($sco, 'forward', $seq, true, $userid); 602 if ($seq->deliverable == false) { 603 scorm_terminate_descendent_attempts($comancestor, $userid, $seq); 604 scorm_seq_end_attempt($comancestor, $userid, $seq->attempt); 605 $seq->currentactivity = $sco; 606 $seq->delivery = null; 607 $seq->exception = 'SB.2.9-9'; 608 return $seq; 609 } else { 610 return $seq; 611 } 612 613 } 614 615 function scorm_seq_choice_flow ($constrained, $traverse, $seq) { 616 $seq = scorm_seq_choice_flow_tree ($constrained, $traverse, $seq); 617 if ($seq->identifiedactivity == null) { 618 $seq->identifiedactivity = $constrained; 619 return $seq; 620 } else { 621 return $seq; 622 } 623 } 624 625 function scorm_seq_choice_flow_tree ($constrained, $traverse, $seq) { 626 $islast = false; 627 $parent = scorm_get_parent ($constrained); 628 if ($traverse == 'forward') { 629 $preord = scorm_get_preorder($constrained); 630 if (count($preorder) == 0 || (count($preorder) == 0 && $preorder[0]->id = $constrained->id)) { 631 // TODO: undefined. 632 $islast = true; // The function is the last activity available. 633 } 634 if ($constrained->parent == '/' || $islast) { 635 $seq->nextactivity = null; 636 return $seq; 637 } 638 $avchildren = scorm_get_available_children($parent); // Available children. 639 if ($avchildren[count($avchildren) - 1]->id == $constrained->id) { 640 $seq = scorm_seq_choice_flow_tree ($parent, 'forward', $seq); 641 return $seq; 642 } else { 643 $i = 0; 644 while ($i < count($avchildren)) { 645 if ($avchildren [$i]->id == $constrained->id) { 646 $seq->nextactivity = $avchildren [$i + 1]; 647 return $seq; 648 } else { 649 $i++; 650 } 651 } 652 } 653 } 654 655 if ($traverse == 'backward') { 656 if ($constrained->parent == '/' ) { 657 $seq->nextactivity = null; 658 return $seq; 659 } 660 661 $avchildren = scorm_get_available_children($parent); // Available children. 662 if ($avchildren [0]->id == $constrained->id) { 663 $seq = scorm_seq_choice_flow_tree ($parent, 'backward', $seq); 664 return $seq; 665 } else { 666 $i = count($avchildren) - 1; 667 while ($i >= 0) { 668 if ($avchildren [$i]->id == $constrained->id) { 669 $seq->nextactivity = $avchildren [$i - 1]; 670 return $seq; 671 } else { 672 $i--; 673 } 674 } 675 } 676 } 677 } 678 679 function scorm_seq_choice_activity_traversal($activity, $userid, $seq, $direction) { 680 if ($direction == 'forward') { 681 $act = scorm_seq_rules_check($activity, 'stopforwardtraversal'); 682 683 if ($act != null) { 684 $seq->reachable = false; 685 $seq->exception = 'SB.2.4-1'; 686 return $seq; 687 } 688 $seq->reachable = false; 689 return $seq; 690 } 691 692 if ($direction == 'backward') { 693 $parentsco = scorm_get_parent($activity); 694 if ($parentsco != null) { 695 if (isset($parentsco->forwardonly) && ($parentsco->forwardonly == true)) { 696 $seq->reachable = false; 697 $seq->exception = 'SB.2.4-2'; 698 return $seq; 699 } else { 700 $seq->reachable = false; 701 $seq->exception = 'SB.2.4-3'; 702 return $seq; 703 } 704 } 705 } 706 $seq->reachable = true; 707 return $seq; 708 } 709 710 // Delivery Request Process. 711 712 function scorm_sequencing_delivery($scoid, $userid, $seq) { 713 714 if (!scorm_is_leaf($seq->delivery)) { 715 $seq->deliveryvalid = false; 716 $seq->exception = 'DB.1.1-1'; 717 return $seq; 718 } 719 $ancestors = scorm_get_ancestors($seq->delivery); 720 $arrpath = array_reverse($ancestors); 721 array_push ($arrpath, $seq->delivery); // Path from the root to the target. 722 723 if (empty($arrpath)) { 724 $seq->deliveryvalid = false; 725 $seq->exception = 'DB.1.1-2'; 726 return $seq; 727 } 728 729 foreach ($arrpath as $activity) { 730 if (scorm_check_activity($activity, $userid)) { 731 $seq->deliveryvalid = false; 732 $seq->exception = 'DB.1.1-3'; 733 return $seq; 734 } 735 } 736 737 $seq->deliveryvalid = true; 738 return $seq; 739 740 } 741 742 function scorm_content_delivery_environment($seq, $userid) { 743 global $DB; 744 745 $act = $seq->currentactivity; 746 if (scorm_seq_is('active', $act->id, $userid)) { 747 $seq->exception = 'DB.2-1'; 748 return $seq; 749 } 750 $track = $DB->get_record('scorm_scoes_track', array('scoid' => $act->id, 751 'userid' => $userid, 752 'element' => 'suspendedactivity')); 753 if ($track != null) { 754 $seq = scorm_clear_suspended_activity($seq->delivery, $seq, $userid); 755 756 } 757 $seq = scorm_terminate_descendent_attempts ($seq->delivery, $userid, $seq); 758 $ancestors = scorm_get_ancestors($seq->delivery); 759 $arrpath = array_reverse($ancestors); 760 array_push ($arrpath, $seq->delivery); 761 foreach ($arrpath as $activity) { 762 if (!scorm_seq_is('active', $activity->id, $userid)) { 763 if (!isset($activity->tracked) || ($activity->tracked == 1)) { 764 if (!scorm_seq_is('suspended', $activity->id, $userid)) { 765 $r = $DB->get_record('scorm_scoes_track', array('scoid' => $activity->id, 766 'userid' => $userid, 767 'element' => 'activityattemptcount')); 768 $r->value = ($r->value) + 1; 769 $DB->update_record('scorm_scoes_track', $r); 770 if ($r->value == 1) { 771 scorm_seq_set('activityprogressstatus', $activity->id, $userid, 'true'); 772 } 773 scorm_insert_track($userid, $activity->scorm, $activity->id, 0, 'objectiveprogressstatus', 'false'); 774 scorm_insert_track($userid, $activity->scorm, $activity->id, 0, 'objectivesatisfiedstatus', 'false'); 775 scorm_insert_track($userid, $activity->scorm, $activity->id, 0, 'objectivemeasurestatus', 'false'); 776 scorm_insert_track($userid, $activity->scorm, $activity->id, 0, 'objectivenormalizedmeasure', 0.0); 777 778 scorm_insert_track($userid, $activity->scorm, $activity->id, 0, 'attemptprogressstatus', 'false'); 779 scorm_insert_track($userid, $activity->scorm, $activity->id, 0, 'attemptcompletionstatus', 'false'); 780 scorm_insert_track($userid, $activity->scorm, $activity->id, 0, 'attemptabsoluteduration', 0.0); 781 scorm_insert_track($userid, $activity->scorm, $activity->id, 0, 'attemptexperiencedduration', 0.0); 782 scorm_insert_track($userid, $activity->scorm, $activity->id, 0, 'attemptcompletionamount', 0.0); 783 } 784 } 785 scorm_seq_set('active', $activity->id, $userid, 'true'); 786 } 787 } 788 $seq->delivery = $seq->currentactivity; 789 scorm_seq_set('suspendedactivity', $activity->id, $userid, 'false'); 790 791 // ONCE THE DELIVERY BEGINS (How should I check that?). 792 793 if (isset($activity->tracked) || ($activity->tracked == 0)) { 794 // How should I track the info and what should I do to not record the information for the activity during delivery? 795 $atabsdur = $DB->get_record('scorm_scoes_track', array('scoid' => $activity->id, 796 'userid' => $userid, 797 'element' => 'attemptabsoluteduration')); 798 $atexpdur = $DB->get_record('scorm_scoes_track', array('scoid' => $activity->id, 799 'userid' => $userid, 800 'element' => 'attemptexperiencedduration')); 801 } 802 return $seq; 803 } 804 805 function scorm_clear_suspended_activity($act, $seq, $userid) { 806 global $DB; 807 $currentact = $seq->currentactivity; 808 $track = $DB->get_record('scorm_scoes_track', array('scoid' => $currentact->id, 809 'userid' => $userid, 810 'element' => 'suspendedactivity')); 811 if ($track != null) { 812 $ancestors = scorm_get_ancestors($act); 813 $commonpos = scorm_find_common_ancestor($ancestors, $currentact); 814 if ($commonpos !== false) { 815 if ($activitypath = array_slice($ancestors, 0, $commonpos)) { 816 if (!empty($activitypath)) { 817 818 foreach ($activitypath as $activity) { 819 if (scorm_is_leaf($activity)) { 820 scorm_seq_set('suspended', $activity->id, $userid, false); 821 } else { 822 $children = scorm_get_children($activity); 823 $bool = false; 824 foreach ($children as $child) { 825 if (scorm_seq_is('suspended', $child->id, $userid)) { 826 $bool = true; 827 } 828 } 829 if (!$bool) { 830 scorm_seq_set('suspended', $activity->id, $userid, false); 831 } 832 } 833 } 834 } 835 } 836 } 837 scorm_seq_set('suspendedactivity', $act->id, $userid, false); 838 } 839 } 840 841 function scorm_select_children_process($scoid, $userid) { 842 global $DB; 843 844 $sco = scorm_get_sco($scoid); 845 if (!scorm_is_leaf($sco)) { 846 if (!scorm_seq_is('suspended', $scoid, $userid) && !scorm_seq_is('active', $scoid, $userid)) { 847 $r = $DB->get_record('scorm_scoes_track', array('scoid' => $scoid, 848 'userid' => $userid, 849 'element' => 'selectiontiming')); 850 851 switch ($r->value) { 852 case 'oneachnewattempt': 853 case 'never': 854 break; 855 856 case 'once': 857 if (!scorm_seq_is('activityprogressstatus', $scoid, $userid)) { 858 if (scorm_seq_is('selectioncountsstatus', $scoid, $userid)) { 859 $childlist = ''; 860 $res = $DB->get_record('scorm_scoes_track', array('scoid' => $scoid, 861 'userid' => $userid, 862 'element' => 'selectioncount')); 863 $i = ($res->value) - 1; 864 $children = scorm_get_children($sco); 865 866 while ($i >= 0) { 867 $pos = array_rand($children); 868 array_push($childlist, $children[$pos]); 869 array_splice($children, $pos, 1); 870 $i--; 871 } 872 sort($childlist); 873 $clist = serialize($childlist); 874 scorm_seq_set('availablechildren', $scoid, $userid, false); 875 scorm_seq_set('availablechildren', $scoid, $userid, $clist); 876 } 877 } 878 break; 879 } 880 } 881 } 882 } 883 884 function scorm_randomize_children_process($scoid, $userid) { 885 global $DB; 886 887 $sco = scorm_get_sco($scoid); 888 if (!scorm_is_leaf($sco)) { 889 if (!scorm_seq_is('suspended', $scoid, $userid) && !scorm_seq_is('active', $scoid, $userid)) { 890 $r = $DB->get_record('scorm_scoes_track', array('scoid' => $scoid, 891 'userid' => $userid, 892 'element' => 'randomizationtiming')); 893 894 switch ($r->value) { 895 case 'never': 896 break; 897 898 case 'oneachnewattempt': 899 case 'once': 900 if (!scorm_seq_is('activityprogressstatus', $scoid, $userid)) { 901 if (scorm_seq_is('randomizechildren', $scoid, $userid)) { 902 $childlist = array(); 903 $res = scorm_get_available_children($sco); 904 $i = count($res) - 1; 905 $children = $res->value; 906 907 while ($i >= 0) { 908 $pos = array_rand($children); 909 array_push($childlist, $children[$pos]); 910 array_splice($children, $pos, 1); 911 $i--; 912 } 913 914 $clist = serialize ($childlist); 915 scorm_seq_set('availablechildren', $scoid, $userid, false); 916 scorm_seq_set('availablechildren', $scoid, $userid, $clist); 917 } 918 } 919 break; 920 } 921 } 922 } 923 } 924 925 function scorm_terminate_descendent_attempts($activity, $userid, $seq) { 926 $ancestors = scorm_get_ancestors($seq->currentactivity); 927 $commonpos = scorm_find_common_ancestor($ancestors, $activity); 928 if ($commonpos !== false) { 929 if ($activitypath = array_slice($ancestors, 1, $commonpos - 2)) { 930 if (!empty($activitypath)) { 931 foreach ($activitypath as $sco) { 932 scorm_seq_end_attempt($sco, $userid, $seq->attempt); 933 } 934 } 935 } 936 } 937 } 938 939 function scorm_sequencing_exception($seq) { 940 global $OUTPUT; 941 if ($seq->exception != null) { 942 switch ($seq->exception) { 943 case 'NB.2.1-1': 944 echo $OUTPUT->notification("Sequencing session has already begun"); 945 break; 946 case 'NB.2.1-2': 947 echo $OUTPUT->notification("Sequencing session has not begun"); 948 break; 949 case 'NB.2.1-3': 950 echo $OUTPUT->notification("Suspended activity is not defined"); 951 break; 952 case 'NB.2.1-4': 953 echo $OUTPUT->notification("Flow Sequencing Control Model Violation"); 954 break; 955 case 'NB.2.1-5': 956 echo $OUTPUT->notification("Flow or Forward only Sequencing Control Model Violation"); 957 break; 958 case 'NB.2.1-6': 959 echo $OUTPUT->notification("No activity is previous to the root"); 960 break; 961 case 'NB.2.1-7': 962 echo $OUTPUT->notification("Unsupported Navigation Request"); 963 break; 964 case 'NB.2.1-8': 965 echo $OUTPUT->notification("Choice Exit Sequencing Control Model Violation"); 966 break; 967 case 'NB.2.1-9': 968 echo $OUTPUT->notification("No activities to consider"); 969 break; 970 case 'NB.2.1-10': 971 echo $OUTPUT->notification("Choice Sequencing Control Model Violation"); 972 break; 973 case 'NB.2.1-11': 974 echo $OUTPUT->notification("Target Activity does not exist"); 975 break; 976 case 'NB.2.1-12': 977 echo $OUTPUT->notification("Current Activity already terminated"); 978 break; 979 case 'NB.2.1-13': 980 echo $OUTPUT->notification("Undefined Navigation Request"); 981 break; 982 983 case 'TB.2.3-1': 984 echo $OUTPUT->notification("Current Activity already terminated"); 985 break; 986 case 'TB.2.3-2': 987 echo $OUTPUT->notification("Current Activity already terminated"); 988 break; 989 case 'TB.2.3-4': 990 echo $OUTPUT->notification("Current Activity already terminated"); 991 break; 992 case 'TB.2.3-5': 993 echo $OUTPUT->notification("Nothing to suspend; No active activities"); 994 break; 995 case 'TB.2.3-6': 996 echo $OUTPUT->notification("Nothing to abandon; No active activities"); 997 break; 998 999 case 'SB.2.1-1': 1000 echo $OUTPUT->notification("Last activity in the tree"); 1001 break; 1002 case 'SB.2.1-2': 1003 echo $OUTPUT->notification("Cluster has no available children"); 1004 break; 1005 case 'SB.2.1-3': 1006 echo $OUTPUT->notification("No activity is previous to the root"); 1007 break; 1008 case 'SB.2.1-4': 1009 echo $OUTPUT->notification("Forward Only Sequencing Control Model Violation"); 1010 break; 1011 1012 case 'SB.2.2-1': 1013 echo $OUTPUT->notification("Flow Sequencing Control Model Violation"); 1014 break; 1015 case 'SB.2.2-2': 1016 echo $OUTPUT->notification("Activity unavailable"); 1017 break; 1018 1019 case 'SB.2.3-1': 1020 echo $OUTPUT->notification("Forward Traversal Blocked"); 1021 break; 1022 case 'SB.2.3-2': 1023 echo $OUTPUT->notification("Forward Only Sequencing Control Model Violation"); 1024 break; 1025 case 'SB.2.3-3': 1026 echo $OUTPUT->notification("No activity is previous to the root"); 1027 break; 1028 1029 case 'SB.2.5-1': 1030 echo $OUTPUT->notification("Sequencing session has already begun"); 1031 break; 1032 1033 case 'SB.2.6-1': 1034 echo $OUTPUT->notification("Sequencing session has already begun"); 1035 break; 1036 case 'SB.2.6-2': 1037 echo $OUTPUT->notification("No Suspended activity is defined"); 1038 break; 1039 1040 case 'SB.2.7-1': 1041 echo $OUTPUT->notification("Sequencing session has not begun"); 1042 break; 1043 case 'SB.2.7-2': 1044 echo $OUTPUT->notification("Flow Sequencing Control Model Violation"); 1045 break; 1046 1047 case 'SB.2.8-1': 1048 echo $OUTPUT->notification("Sequencing session has not begun"); 1049 break; 1050 case 'SB.2.8-2': 1051 echo $OUTPUT->notification("Flow Sequencing Control Model Violation"); 1052 break; 1053 1054 case 'SB.2.9-1': 1055 echo $OUTPUT->notification("No target for Choice"); 1056 break; 1057 case 'SB.2.9-2': 1058 echo $OUTPUT->notification("Target Activity does not exist or is unavailable"); 1059 break; 1060 case 'SB.2.9-3': 1061 echo $OUTPUT->notification("Target Activity hidden from choice"); 1062 break; 1063 case 'SB.2.9-4': 1064 echo $OUTPUT->notification("Choice Sequencing Control Model Violation"); 1065 break; 1066 case 'SB.2.9-5': 1067 echo $OUTPUT->notification("No activities to consider"); 1068 break; 1069 case 'SB.2.9-6': 1070 echo $OUTPUT->notification("Unable to activate target; target is not a child of the Current Activity"); 1071 break; 1072 case 'SB.2.9-7': 1073 echo $OUTPUT->notification("Choice Exit Sequencing Control Model Violation"); 1074 break; 1075 case 'SB.2.9-8': 1076 echo $OUTPUT->notification("Unable to choose target activity - constrained choice"); 1077 break; 1078 case 'SB.2.9-9': 1079 echo $OUTPUT->notification("Choice Request Prevented by Flow-only Activity"); 1080 break; 1081 1082 case 'SB.2.10-1': 1083 echo $OUTPUT->notification("Sequencing session has not begun"); 1084 break; 1085 case 'SB.2.10-2': 1086 echo $OUTPUT->notification("Current Activity is active or suspended"); 1087 break; 1088 case 'SB.2.10-3': 1089 echo $OUTPUT->notification("Flow Sequencing Control Model Violation"); 1090 break; 1091 1092 case 'SB.2.11-1': 1093 echo $OUTPUT->notification("Sequencing session has not begun"); 1094 break; 1095 case 'SB.2.11-2': 1096 echo $OUTPUT->notification("Current Activity has not been terminated"); 1097 break; 1098 1099 case 'SB.2.12-2': 1100 echo $OUTPUT->notification("Undefined Sequencing Request"); 1101 break; 1102 1103 case 'DB.1.1-1': 1104 echo $OUTPUT->notification("Cannot deliver a non-leaf activity"); 1105 break; 1106 case 'DB.1.1-2': 1107 echo $OUTPUT->notification("Nothing to deliver"); 1108 break; 1109 case 'DB.1.1-3': 1110 echo $OUTPUT->notification("Activity unavailable"); 1111 break; 1112 1113 case 'DB.2-1': 1114 echo $OUTPUT->notification("Identified activity is already active"); 1115 break; 1116 1117 } 1118 1119 } 1120 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |