Index: locallib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/mod/scorm/locallib.php,v
retrieving revision 1.46.2.8
diff -c -r1.46.2.8 locallib.php
*** locallib.php	3 Aug 2008 22:17:16 -0000	1.46.2.8
--- locallib.php	7 Aug 2008 21:45:47 -0000
***************
*** 221,226 ****
--- 221,256 ----
          return false;
      }
  }
+ 
+ /**
+ * Returns an object (array) containing all the scoes data related to the given sco ID
+ *
+ * @param integer $id The sco ID
+ * @param integer $organisation an organisation ID - defaults to false if not required
+ * @return mixed (false if there are no scoes or an array)
+ */
+ 
+ function scorm_get_scoes($id,$organisation=false) {
+     $organizationsql = '';
+     if (!empty($organisation)) {
+         $organizationsql = "AND organization='$organisation'";
+     }
+     if ($scoes = get_records_select('scorm_scoes',"scorm='$id' $organizationsql order by id ASC")) {
+         // drop keys so that it is a simple array as expected
+         $scoes = array_values($scoes);
+         foreach ($scoes as $sco) {
+             if ($scodatas = get_records('scorm_scoes_data','scoid',$sco->id)) {
+                 foreach ($scodatas as $scodata) {
+                     $sco->{$scodata->name} = stripslashes_safe($scodata->value);
+                 }
+             }
+         }
+         return $scoes;
+     } else {
+         return false;
+     }
+ }
+ 
  function scorm_insert_track($userid,$scormid,$scoid,$attempt,$element,$value) {
      $id = null;
      if ($track = get_record_select('scorm_scoes_track',"userid='$userid' AND scormid='$scormid' AND scoid='$scoid' AND attempt='$attempt' AND element='$element'")) {
Index: datamodels/aicclib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/mod/scorm/datamodels/aicclib.php,v
retrieving revision 1.5.2.6
diff -c -r1.5.2.6 aicclib.php
*** datamodels/aicclib.php	28 Jul 2008 22:42:57 -0000	1.5.2.6
--- datamodels/aicclib.php	7 Aug 2008 21:45:48 -0000
***************
*** 322,334 ****
      //
      // Get the current organization infos
      //
-     $organizationsql = '';
      if (!empty($currentorg)) {
          if (($organizationtitle = get_field('scorm_scoes','title','scorm',$scorm->id,'identifier',$currentorg)) != '') {
              $result->toc .= "\t<li>$organizationtitle</li>\n";
              $tocmenus[] = $organizationtitle;
          }
-         $organizationsql = "AND organization='$currentorg'";
      }
      //
      // If not specified retrieve the last attempt number
--- 322,332 ----
***************
*** 337,352 ****
          $attempt = scorm_get_last_attempt($scorm->id, $user->id);
      }
      $result->attemptleft = $scorm->maxattempt - $attempt;
!     if ($scoes = get_records_select('scorm_scoes',"scorm='$scorm->id' $organizationsql order by id ASC")){
!         // drop keys so that we can access array sequentially
!         $scoes = array_values($scoes); 
          //
          // Retrieve user tracking data for each learning object
          // 
          $usertracks = array();
          foreach ($scoes as $sco) {
              if (!empty($sco->launch)) {
!                 if ($usertrack=scorm_get_tracks($sco->id,$user->id,$attempt)) {
                      if ($usertrack->status == '') {
                          $usertrack->status = 'notattempted';
                      }
--- 335,348 ----
          $attempt = scorm_get_last_attempt($scorm->id, $user->id);
      }
      $result->attemptleft = $scorm->maxattempt - $attempt;
!     if ($scoes = scorm_get_scoes($scorm->id, $currentorg)){
          //
          // Retrieve user tracking data for each learning object
          // 
          $usertracks = array();
          foreach ($scoes as $sco) {
              if (!empty($sco->launch)) {
!                 if ($usertrack = scorm_get_tracks($sco->id,$user->id,$attempt)) {
                      if ($usertrack->status == '') {
                          $usertrack->status = 'notattempted';
                      }
***************
*** 362,376 ****
          $findnext = false;
          $parents[$level]='/';
          
!         foreach ($scoes as $pos=>$sco) {
              $isvisible = false;
              $sco->title = stripslashes($sco->title);
!             if ($optionaldatas = scorm_get_sco($sco->id, SCO_DATA)) {
!                 if (!isset($optionaldatas->isvisible) || (isset($optionaldatas->isvisible) && ($optionaldatas->isvisible == 'true'))) {
!                     $isvisible = true;
!                 }
!             }
!             else {
                  $isvisible = true;
              }
              if ($parents[$level]!=$sco->parent) {
--- 358,367 ----
          $findnext = false;
          $parents[$level]='/';
          
!         foreach ($scoes as $pos => $sco) {
              $isvisible = false;
              $sco->title = stripslashes($sco->title);
!             if (!isset($sco->isvisible) || (isset($sco->isvisible) && ($sco->isvisible == 'true'))) {
                  $isvisible = true;
              }
              if ($parents[$level]!=$sco->parent) {
***************
*** 409,418 ****
                  $nextsco = false;
              }
              $nextisvisible = false;
!             if (($nextsco !== false) && ($optionaldatas = scorm_get_sco($nextsco->id, SCO_DATA))) {
!                 if (!isset($optionaldatas->isvisible) || (isset($optionaldatas->isvisible) && ($optionaldatas->isvisible == 'true'))) {
!                     $nextisvisible = true;
!                 }
              }
              if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
                  $sublist++;
--- 400,407 ----
                  $nextsco = false;
              }
              $nextisvisible = false;
!             if (!isset($nextsco->isvisible) || (isset($nextsco->isvisible) && ($nextsco->isvisible == 'true'))) {
!                 $nextisvisible = true;
              }
              if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
                  $sublist++;
***************
*** 469,480 ****
                          }
                      }
                      if ($sco->id == $scoid) {
-                         $scodata = scorm_get_sco($sco->id, SCO_DATA);
                          $startbold = '<b>';
                          $endbold = '</b>';
                          $findnext = true;
!                         $shownext = isset($scodata->next) ? $scodata->next : 0;
!                         $showprev = isset($scodata->previous) ? $scodata->previous : 0;
                      }
                  
                      if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
--- 458,468 ----
                          }
                      }
                      if ($sco->id == $scoid) {
                          $startbold = '<b>';
                          $endbold = '</b>';
                          $findnext = true;
!                         $shownext = isset($sco->next) ? $sco->next : 0;
!                         $showprev = isset($sco->previous) ? $sco->previous : 0;
                      }
                  
                      if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
Index: datamodels/scorm_12lib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/mod/scorm/datamodels/scorm_12lib.php,v
retrieving revision 1.11.2.5
diff -c -r1.11.2.5 scorm_12lib.php
*** datamodels/scorm_12lib.php	18 Jul 2008 06:27:12 -0000	1.11.2.5
--- datamodels/scorm_12lib.php	7 Aug 2008 21:45:49 -0000
***************
*** 1,6 ****
  <?php // $Id: scorm_12lib.php,v 1.11.2.5 2008/07/18 06:27:12 piers Exp $
  
! function scorm_eval_prerequisites($prerequisites,$usertracks) {
      $element = '';
      $stack = array();
      $statuses = array(
--- 1,18 ----
  <?php // $Id: scorm_12lib.php,v 1.11.2.5 2008/07/18 06:27:12 piers Exp $
  
! /**
! * This is really a little language parser for AICC_SCRIPT
! * evaluates the expression and returns a boolean answer
! * see 2.3.2.5.1. Sequencing/Navigation Today  - from the SCORM 1.2 spec (CAM).
! *
! * @param string $prerequisites the aicc_script prerequisites expression
! * @param array  $usertracks the tracked user data of each SCO visited
! * @return boolean
! */
! function scorm_eval_prerequisites($prerequisites, $usertracks) {
!     
!     // this is really a little language parser - AICC_SCRIPT is the reference 
!     // see 2.3.2.5.1. Sequencing/Navigation Today  - from the SCORM 1.2 spec
      $element = '';
      $stack = array();
      $statuses = array(
***************
*** 18,155 ****
                  'n' => 'notattempted'
                  );
      $i=0;  
!     while ($i<strlen($prerequisites)) {
!         $symbol = $prerequisites[$i];
!         switch ($symbol) {
!             case '&':
!             case '|':
!                 $symbol .= $symbol;
!             case '~':
!             case '(':
!             case ')':
!             case '*':
!                 $element = trim($element);
!                 
!                 if (!empty($element)) {
!                     $element = trim($element);
!                     if (isset($usertracks[$element])) {
!                         $element = '((\''.$usertracks[$element]->status.'\' == \'completed\') || '.
!                                   '(\''.$usertracks[$element]->status.'\' == \'passed\'))'; 
!                     } else if (($operator = strpos($element,'=')) !== false) {
!                         $item = trim(substr($element,0,$operator));
!                         if (!isset($usertracks[$item])) {
!                             return false;
!                         }
!                         
!                         $value = trim(trim(substr($element,$operator+1)),'"');
!                         if (isset($statuses[$value])) {
!                             $status = $statuses[$value];
!                         } else {
!                             return false;
!                         }
!                                               
!                         $element = '(\''.$usertracks[$item]->status.'\' == \''.$status.'\')';
!                     } else if (($operator = strpos($element,'<>')) !== false) {
!                         $item = trim(substr($element,0,$operator));
!                         if (!isset($usertracks[$item])) {
!                             return false;
!                         }
!                         
!                         $value = trim(trim(substr($element,$operator+2)),'"');
!                         if (isset($statuses[$value])) {
!                             $status = $statuses[$value];
!                         } else {
!                             return false;
!                         }
!                         
!                         $element = '(\''.$usertracks[$item]->status.'\' != \''.$status.'\')';
!                     } else if (is_numeric($element)) {
!                         if ($symbol == '*') {
!                             $symbol = '';
!                             $open = strpos($prerequisites,'{',$i);
!                             $opened = 1;
!                             $closed = 0;
!                             for ($close=$open+1; (($opened > $closed) && ($close<strlen($prerequisites))); $close++) { 
!                                  if ($prerequisites[$close] == '}') {
!                                      $closed++;
!                                  } else if ($prerequisites[$close] == '{') {
!                                      $opened++;
!                                  }
!                             } 
!                             $i = $close;
!                             
!                             $setelements = explode(',', substr($prerequisites, $open+1, $close-($open+1)-1));
!                             $settrue = 0;
!                             foreach ($setelements as $setelement) {
!                                 if (scorm_eval_prerequisites($setelement,$usertracks)) {
!                                     $settrue++;
!                                 }
!                             }
!                             
!                             if ($settrue >= $element) {
!                                 $element = 'true'; 
!                             } else {
!                                 $element = 'false';
!                             }
!                         }
!                     } else {
!                         return false;
!                     }
!                     
!                     array_push($stack,$element);
!                     $element = '';
                  }
!                 if ($symbol == '~') {
!                     $symbol = '!';
                  }
!                 if (!empty($symbol)) {
!                     array_push($stack,$symbol);
                  }
!             break;
!             default:
!                 $element .= $symbol;
!             break;
!         }
!         $i++;
!     }
!     if (!empty($element)) {
!         $element = trim($element);
!         if (isset($usertracks[$element])) {
!             $element = '((\''.$usertracks[$element]->status.'\' == \'completed\') || '.
!                        '(\''.$usertracks[$element]->status.'\' == \'passed\'))'; 
!         } else if (($operator = strpos($element,'=')) !== false) {
!             $item = trim(substr($element,0,$operator));
!             if (!isset($usertracks[$item])) {
!                 return false;
!             }
!             
!             $value = trim(trim(substr($element,$operator+1)),'"');
!             if (isset($statuses[$value])) {
!                 $status = $statuses[$value];
!             } else {
!                 return false;
!             }
!             
!             $element = '(\''.$usertracks[$item]->status.'\' == \''.$status.'\')';
!         } else if (($operator = strpos($element,'<>')) !== false) {
!             $item = trim(substr($element,0,$operator));
!             if (!isset($usertracks[$item])) {
!                 return false;
!             }
!             
!             $value = trim(trim(substr($element,$operator+1)),'"');
!             if (isset($statuses[$value])) {
!                 $status = $statuses[$value];
              } else {
!                 return false;
              }
!             
!             $element = '(\''.$usertracks[$item]->status.'\' != \''.trim($status).'\')';
!         } else {
!             return false;
          }
!         
!         array_push($stack,$element);
      }
      return eval('return '.implode($stack).';');
  }
--- 30,108 ----
                  'n' => 'notattempted'
                  );
      $i=0;  
! 
!     // expand the amp entities
!     $prerequisites = preg_replace('/&amp;/', '&', $prerequisites);
!     // find all my parsable tokens
!     $prerequisites = preg_replace('/(&|\||\(|\)|\~)/', '\t$1\t', $prerequisites);
!     // expand operators
!     $prerequisites = preg_replace('/&/', '&&', $prerequisites);
!     $prerequisites = preg_replace('/\|/', '||', $prerequisites);
!     // now - grab all the tokens
!     $elements = explode('\t', trim($prerequisites));
! 
!     // process each token to build an expression to be evaluated
!     $stack = array();
!     foreach ($elements as $element) {
!         $element = trim($element);
!         if (empty($element)) {
!             continue;
!         }
!         if (!preg_match('/^(&&|\|\||\(|\))$/', $element)) {
!             // create each individual expression
!             // search for ~ = <> X*{}
!     
!             // sets like 3*{S34, S36, S37, S39}
!             if (preg_match('/^(\d+)\*\{(.+)\}$/', $element, $matches)) {
!                 $repeat = $matches[1];
!                 $set = explode(',', $matches[2]);
!                 $count = 0;
!                 foreach ($set as $setelement) {
!                   if (isset($usertracks[$setelement]) &&
!                       ($usertracks[$setelement]->status == 'completed' || $usertracks[$element]->status == 'passed')) {
!                       $count++;
!                   }
                  }
!                 if ($count >= $repeat) {
!                     $element = 'true';
!                 } else {
!                     $element = 'false';
                  }
!     
!             // ~ Not
!             } else if ($element == '~') {
!                 $element = '!';
!     
!             // = | <>
!             } else if (preg_match('/^(.+)(\=|\<\>)(.+)$/', $element, $matches)) {
!                 $element = trim($matches[1]);
!                 if (isset($usertracks[$element])) {
!                     $value = trim(preg_replace('/(\'|\")/', '', $matches[3]));
!                     if (isset($statuses[$value])) {
!                         $value = $statuses[$value];
!                     }
!                     if ($matches[2] == '<>') {
!                         $oper = '!=';
!                     } else {
!                       $oper = '==';
!                     }
!                     $element = '(\''.$usertracks[$element]->status.'\' '.$oper.' \''.$value.'\')';
!                 } else {
!                   $element = 'false';
                  }
!     
!             // everything else must be an element defined like S45 ...
              } else {
!                 if (isset($usertracks[$element]) &&
!                     ($usertracks[$element]->status == 'completed' || $usertracks[$element]->status == 'passed')) {
!                     $element = 'true';
!                 } else {
!                     $element = 'false';
!                 }
              }
!     
          }
!         $stack []= ' '.$element.' ';
      }
      return eval('return '.implode($stack).';');
  }
***************
*** 173,185 ****
      //
      // Get the current organization infos
      //
-     $organizationsql = '';
      if (!empty($currentorg)) {
          if (($organizationtitle = get_field('scorm_scoes','title','scorm',$scorm->id,'identifier',$currentorg)) != '') {
              $result->toc .= "\t<li>$organizationtitle</li>\n";
              $tocmenus[] = $organizationtitle;
          }
-         $organizationsql = "AND organization='$currentorg'";
      }
      //
      // If not specified retrieve the last attempt number
--- 126,136 ----
***************
*** 188,203 ****
          $attempt = scorm_get_last_attempt($scorm->id, $user->id);
      }
      $result->attemptleft = $scorm->maxattempt - $attempt;
!     if ($scoes = get_records_select('scorm_scoes',"scorm='$scorm->id' $organizationsql order by id ASC")){
!         // drop keys so that we can access array sequentially
!         $scoes = array_values($scoes); 
          //
          // Retrieve user tracking data for each learning object
          //
          $usertracks = array();
          foreach ($scoes as $sco) {
              if (!empty($sco->launch)) {
!                 if ($usertrack=scorm_get_tracks($sco->id,$user->id,$attempt)) {
                      if ($usertrack->status == '') {
                          $usertrack->status = 'notattempted';
                      }
--- 139,152 ----
          $attempt = scorm_get_last_attempt($scorm->id, $user->id);
      }
      $result->attemptleft = $scorm->maxattempt - $attempt;
!     if ($scoes = scorm_get_scoes($scorm->id, $currentorg)){
          //
          // Retrieve user tracking data for each learning object
          //
          $usertracks = array();
          foreach ($scoes as $sco) {
              if (!empty($sco->launch)) {
!                 if ($usertrack = scorm_get_tracks($sco->id,$user->id,$attempt)) {
                      if ($usertrack->status == '') {
                          $usertrack->status = 'notattempted';
                      }
***************
*** 213,230 ****
          $findnext = false;
          $parents[$level]='/';
          
!         foreach ($scoes as $pos=>$sco) {
              $isvisible = false;
              $sco->title = stripslashes($sco->title);
!             if ($optionaldatas = scorm_get_sco($sco->id, SCO_DATA)) {
!                 if (!isset($optionaldatas->isvisible) || (isset($optionaldatas->isvisible) && ($optionaldatas->isvisible == 'true'))) {
!                     $isvisible = true;
!                 }
!             }
!             else{
                  $isvisible = true;
              }
!             if ($parents[$level]!=$sco->parent) {
                  if ($newlevel = array_search($sco->parent,$parents)) {
                      for ($i=0; $i<($level-$newlevel); $i++) {
                          $result->toc .= "\t\t</ul></li>\n";
--- 162,174 ----
          $findnext = false;
          $parents[$level]='/';
          
!         foreach ($scoes as $pos => $sco) {
              $isvisible = false;
              $sco->title = stripslashes($sco->title);
!             if (!isset($sco->isvisible) || (isset($sco->isvisible) && ($sco->isvisible == 'true'))) {
                  $isvisible = true;
              }
!             if ($parents[$level] != $sco->parent) {
                  if ($newlevel = array_search($sco->parent,$parents)) {
                      for ($i=0; $i<($level-$newlevel); $i++) {
                          $result->toc .= "\t\t</ul></li>\n";
***************
*** 248,254 ****
                          $result->toc .= $closelist;
                          $level = $i;
                      }
!                     $parents[$level]=$sco->parent;
                  }
              }
              if ($isvisible) {
--- 192,198 ----
                          $result->toc .= $closelist;
                          $level = $i;
                      }
!                     $parents[$level] = $sco->parent;
                  }
              }
              if ($isvisible) {
***************
*** 260,269 ****
                  $nextsco = false;
              }
              $nextisvisible = false;
!             if (($nextsco !== false) && ($optionaldatas = scorm_get_sco($nextsco->id, SCO_DATA))) {
!                 if (!isset($optionaldatas->isvisible) || (isset($optionaldatas->isvisible) && ($optionaldatas->isvisible == 'true'))) {
!                     $nextisvisible = true;
!                 }
              }
              if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
                  $sublist++;
--- 204,211 ----
                  $nextsco = false;
              }
              $nextisvisible = false;
!             if (($nextsco !== false) && (!isset($nextsco->isvisible) || (isset($nextsco->isvisible) && ($nextsco->isvisible == 'true')))) {
!                 $nextisvisible = true;
              }
              if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
                  $sublist++;
***************
*** 320,331 ****
                          }
                      }
                      if ($sco->id == $scoid) {
-                         $scodata = scorm_get_sco($sco->id, SCO_DATA);
                          $startbold = '<b>';
                          $endbold = '</b>';
                          $findnext = true;
!                         $shownext = isset($scodata->next) ? $scodata->next : 0;
!                         $showprev = isset($scodata->previous) ? $scodata->previous : 0;
                      }
                  
                      if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
--- 262,272 ----
                          }
                      }
                      if ($sco->id == $scoid) {
                          $startbold = '<b>';
                          $endbold = '</b>';
                          $findnext = true;
!                         $shownext = isset($sco->next) ? $sco->next : 0;
!                         $showprev = isset($sco->previous) ? $sco->previous : 0;
                      }
                  
                      if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
Index: datamodels/scorm_13lib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/mod/scorm/datamodels/scorm_13lib.php,v
retrieving revision 1.7.2.4
diff -c -r1.7.2.4 scorm_13lib.php
*** datamodels/scorm_13lib.php	18 Jul 2008 06:27:12 -0000	1.7.2.4
--- datamodels/scorm_13lib.php	7 Aug 2008 21:45:49 -0000
***************
*** 19,31 ****
      //
      // Get the current organization infos
      //
-     $organizationsql = '';
      if (!empty($currentorg)) {
          if (($organizationtitle = get_field('scorm_scoes','title','scorm',$scorm->id,'identifier',$currentorg)) != '') {
              $result->toc .= "\t<li>$organizationtitle</li>\n";
              $tocmenus[] = $organizationtitle;
          }
-         $organizationsql = "AND organization='$currentorg'";
      }
      //
      // If not specified retrieve the last attempt number
--- 19,29 ----
***************
*** 34,59 ****
          $attempt = scorm_get_last_attempt($scorm->id, $user->id);
      }
      $result->attemptleft = $scorm->maxattempt - $attempt;
!     if ($scoes = get_records_select('scorm_scoes',"scorm='$scorm->id' $organizationsql order by id ASC")){
!         // drop keys so that we can access array sequentially
!         $scoes = array_values($scoes); 
          //
          // Retrieve user tracking data for each learning object
          // 
      
          $usertracks = array();
-         $optionaldatas = array();
          foreach ($scoes as $sco) {
              if (!empty($sco->launch)) {
!                 if ($usertrack=scorm_get_tracks($sco->id,$user->id,$attempt)) {
                      if ($usertrack->status == '') {
                          $usertrack->status = 'notattempted';
                      }
                      $usertracks[$sco->identifier] = $usertrack;
                  }
-                 if ($optionaldata = scorm_get_sco($sco->id, SCO_DATA)) {
-                     $optionaldatas[$sco->identifier] = $optionaldata;
-                 }
              }
          }
  
--- 32,51 ----
          $attempt = scorm_get_last_attempt($scorm->id, $user->id);
      }
      $result->attemptleft = $scorm->maxattempt - $attempt;
!     if ($scoes = scorm_get_scoes($scorm->id, $currentorg)){
          //
          // Retrieve user tracking data for each learning object
          // 
      
          $usertracks = array();
          foreach ($scoes as $sco) {
              if (!empty($sco->launch)) {
!                 if ($usertrack = scorm_get_tracks($sco->id,$user->id,$attempt)) {
                      if ($usertrack->status == '') {
                          $usertrack->status = 'notattempted';
                      }
                      $usertracks[$sco->identifier] = $usertrack;
                  }
              }
          }
  
***************
*** 63,76 ****
          $nextid = 0;
          $findnext = false;
          $parents[$level]='/';
!         foreach ($scoes as $pos=>$sco) {
              $isvisible = false;
              $sco->title = stripslashes($sco->title);
!             if (isset($optionaldatas[$sco->identifier])) {
!                 if (!isset($optionaldatas[$sco->identifier]->isvisible) || 
!                    (isset($optionaldatas[$sco->identifier]->isvisible) && ($optionaldatas[$sco->identifier]->isvisible == 'true'))) {
!                     $isvisible = true;
!                 }
              }
              if ($parents[$level]!=$sco->parent) {
                  if ($newlevel = array_search($sco->parent,$parents)) {
--- 55,65 ----
          $nextid = 0;
          $findnext = false;
          $parents[$level]='/';
!         foreach ($scoes as $pos => $sco) {
              $isvisible = false;
              $sco->title = stripslashes($sco->title);
!             if (!isset($sco->isvisible) || (isset($sco->isvisible) && ($sco->isvisible == 'true'))) {
!                 $isvisible = true;
              }
              if ($parents[$level]!=$sco->parent) {
                  if ($newlevel = array_search($sco->parent,$parents)) {
***************
*** 105,115 ****
                  $nextsco = false;
              }
              $nextisvisible = false;
!             if (($nextsco !== false) && (isset($optionaldatas[$nextsco->identifier]))) {
!                 if (!isset($optionaldatas[$nextsco->identifier]->isvisible) || 
!                    (isset($optionaldatas[$nextsco->identifier]->isvisible) && ($optionaldatas[$nextsco->identifier]->isvisible == 'true'))) {
!                     $nextisvisible = true;
!                 }
              }
              if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && 
                 (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
--- 94,101 ----
                  $nextsco = false;
              }
              $nextisvisible = false;
!             if (!isset($nextsco->isvisible) || (isset($nextsco->isvisible) && ($nextsco->isvisible == 'true'))) {
!                 $nextisvisible = true;
              }
              if ($nextisvisible && ($nextsco !== false) && ($sco->parent != $nextsco->parent) && 
                 (($level==0) || (($level>0) && ($nextsco->parent == $sco->identifier)))) {
***************
*** 172,179 ****
                          $startbold = '<b>';
                          $endbold = '</b>';
                          $findnext = true;
!                         $shownext = isset($optionaldatas[$sco->identifier]->next) ? $optionaldatas[$sco->identifier]->next : 0;
!                         $showprev = isset($optionaldatas[$sco->identifier]->prev) ? $optionaldatas[$sco->identifier]->prev : 0;
                      }
                  
                      if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {
--- 158,165 ----
                          $startbold = '<b>';
                          $endbold = '</b>';
                          $findnext = true;
!                         $shownext = isset($sco->next) ? $sco->next : 0;
!                         $showprev = isset($sco->prev) ? $sco->prev : 0;
                      }
                  
                      if (($nextid == 0) && (scorm_count_launchable($scorm->id,$currentorg) > 1) && ($nextsco!==false) && (!$findnext)) {

